一、前言Dubbo RPC服务框架支持丰富的传输协议、序列化方式等通讯相关的配置和扩展。dubbo执行一次RPC请求的过程大致如下:消费者(Consumer)向注册中心(Registry)执行RPC请求,注册中心分配服务URL并路由到具体服务提供方(Provider),消费者和服务提供方建立网络连接,服务提供方在本地创建连接池对象并提供远程服务,对于长连接类型协议(如dubbo协议)将保持连接,减少握手认证,调用过程中可以避免频繁建立和断开连接导致的性能开销,保持长连接需要有心跳包的发送,所以对于非频繁调用的服务保持连接同样会有消耗。更多关于dubbo详细介绍请参照官方文档(http://alibaba./dubbo-doc-static/Home-zh.htm)。 1、支持常见的传输协议:RMI、Dubbo、Hessain、WebService、Http等,其中Dubbo和RMI协议基于TCP实现,Hessian和WebService基于HTTP实现。 2、传输框架:Netty、Mina、以及基于servlet等方式。 3、序列化方式:Hessian2、dubbo、JSON(fastjson 实现)、JAVA、SOAP 等。 本文主要基于dubbo框架下的通讯协议进行性能测试对比。
二、测试方案基于dubbo 2.5.3框架,使用zookeeper作为dubbo服务注册中心,分别以单线程和多线程的方式测试以下方案:
三、传输测试数据1、单POJO对象,嵌套复杂集合类型 2、POJO集合,包含100个单POJO对象 3、1K字符串 4、100K字符串 5、1M字符串
四、服务接口和实现1、服务接口相关代码: 1 package ibusiness; 2 3 import java.util.List; 4 5 import model.*; 6 7 public interface IBusinessOrder { 8 public String SendStr(String str); 9 10 public List<OrderInfo> LoadOrders(List<OrderInfo> orders); 11 12 public OrderInfo LoadOrder(OrderInfo order); 13 } 2、服务实现相关代码,测试数据在服务器端不做任何处理原样返回:
View Code
五、单线程测试1、测试仅记录rpc调用时间,测试数据的读取组装以及首次建立连接等相关耗时时间不作统计,循环执行100次取平均值。 2、服务消费方测试代码
View Code
3、测试数据耗时记录 A、dubbo 协议、netty 传输、hessian2 序列化 <dubbo:protocol name="dubbo" server="netty" port="30001" serialization="hessian2" />
B、dubbo 协议、netty 传输、dubbo 序列化 <dubbo:protocol name="dubbo" server="netty" port="30001" serialization="dubbo" />
C、dubbo 协议、netty 传输、java 序列化 <dubbo:protocol name="dubbo" server="netty" port="30001" serialization="java" />
D、RMI 协议、netty 传输、java 序列化 <dubbo:protocol name="rmi" server="netty" port="1099" serialization="java" />
E、RMI 协议、netty 传输、hessian2 序列化 <dubbo:protocol name="rmi" server="netty" port="1099" serialization="hessian2" />
F、Hessian协议、servlet(tomcat容器)、hessian2 序列化 <dubbo:protocol name="hessian" port="8080" server="servlet" serialization="hessian2" />
G、WebService协议、servlet(tomcat容器)、SOAP序列化 <dubbo:protocol name="webservice" port="8080" server="servlet" />
4、性能对比
六、多线程测试1、由于测试机器配置较低,为了避免达到CPU瓶颈,测试设定服务消费方Consumer并发10个线程,每个线程连续对远程方法执行5次调用,服务提供方设置允许最大连接数100个,同时5个连接并行执行,超时时间设置为5000ms,要求所有事务都能正确返回没有异常,统计包含首次建立连接的消耗时间。 2、服务消费方测试代码
3、测试数据耗时记录 A、dubbo 协议、netty 传输、hessian2 序列化 <dubbo:protocol name="dubbo" server="netty" port="30001" serialization="hessian2" />
B、dubbo 协议、netty 传输、dubbo 序列化 <dubbo:protocol name="dubbo" server="netty" port="30001" serialization="dubbo" />
C、dubbo 协议、netty 传输、java 序列化 <dubbo:protocol name="dubbo" server="netty" port="30001" serialization="java" />
D、RMI 协议、netty 传输、java 序列化 <dubbo:protocol name="rmi" server="netty" port="1099" serialization="java" />
E、RMI 协议、netty 传输、hessian2 序列化 <dubbo:protocol name="rmi" server="netty" port="1099" serialization="hessian2" />
F、Hessian协议、servlet、hessian2 序列化 <dubbo:protocol name="hessian" port="8080" server="servlet" serialization="hessian2" />
G、WebService协议、servlet、SOAP序列化 <dubbo:protocol name="webservice" port="8080" server="servlet" />
4、性能对比 七、性能分析测试过程中尽管考虑了非常多的影响因素,但仍然有很多局限性,包括连接数限制、并发量、线程池策略、Cache、IO、硬件性能瓶颈等等因素,而且各自的适用场景不同,测试结果仅供参考。 从单线程测试结果可以看出,dubbo协议采用NIO复用单一长连接更适合满足高并发小数据量的rpc调用,而在大数据量下的传输性能并不好,建议使用rmi协议,多线程测试中dubbo协议对小数据量的rpc调用同样保持优势,在大数据量的传输中由于长连接的原因对比rmi协议传输耗时差距并不明显,这点同样验证了上述观点。关于数据的序列化方式选择需要考虑序列化和反序列化的效率问题,传输内容的大小,以及格式的兼容性约束,其中hessian2作为duobb协议下的默认序列化方式,推荐使用。 如果有描述错误或者不当的地方欢迎指正。 |
|