一、前言
Dubbo RPC服务框架支持丰富的传输协议、序列化方式等通讯相关的配置和扩展。dubbo执行一次RPC请求的过程大致如下:消费者(Consumer)向注册中心(Registry)执行RPC请求,注册中心分配服务URL并路由到具体服务提供方(Provider),消费者和服务提供方建立网络连接,服务提供方在本地创建连接池对象并提供远程服务,对于长连接类型协议(如dubbo协议)将保持连接,减少握手认证,调用过程中可以避免频繁建立和断开连接导致的性能开销,保持长连接需要有心跳包的发送,所以对于非频繁调用的服务保持连接同样会有消耗。更多关于dubbo详细介绍请参照官方文档(http://alibaba.github.io/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服务注册中心,分别以单线程和多线程的方式测试以下方案:
Protocol | Transporter | Serialization | Remark | |
A | dubbo 协议 | netty | hessian2 | |
B | dubbo 协议 | netty | dubbo | |
C | dubbo 协议 | netty | java | |
D | RMI 协议 | netty | java | |
E | RMI 协议 | netty | hessian2 | |
F | Hessian 协议 | servlet | hessian2 | Hessian,基于tomcat容器 |
G | WebService 协议 | servlet | SOAP | CXF,基于tomcat容器 |
三、传输测试数据
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、服务实现相关代码,测试数据在服务器端不做任何处理原样返回:
1 package business; 2 3 import ibusiness.IBusinessOrder; 4 5 import java.util.List; 6 7 import model.*; 8 9 public class BusinessOrder implements IBusinessOrder { 10 public String SendStr(String str) { 11 return str; 12 } 13 14 public List<OrderInfo> LoadOrders(List<OrderInfo> orders) { 15 return orders; 16 } 17 18 public OrderInfo LoadOrder(OrderInfo order) { 19 return order; 20 } 21 }
五、单线程测试
1、测试仅记录rpc调用时间,测试数据的读取组装以及首次建立连接等相关耗时时间不作统计,循环执行100次取平均值。
2、服务消费方测试代码
1 import java.util.List; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.FileSystemXmlApplicationContext; 5 6 import com.alibaba.dubbo.rpc.service.EchoService; 7 import common.Common; 8 9 import ibusiness.*; 10 import model.*; 11 12 public class Program { 13 public static void main(String[] args) throws Exception { 14 15 ApplicationContext ctx = new FileSystemXmlApplicationContext("src//applicationContext.xml"); 16 IBusinessOrder orderBusiness = (IBusinessOrder) ctx.getBean("orderBusiness"); 17 18 // EchoService echoService = (EchoService) orderBusiness; 19 // String status = echoService.$echo("OK").toString(); 20 // if (!status.equals("OK")) { 21 // System.out.println("orderBusiness out of service!"); 22 // return; 23 // } else { 24 // System.out.println("orderBusiness in service !"); 25 // } 26 27 long startMili, endMili; 28 int loop = 100; 29 30 // 单个pojo 31 try { 32 OrderInfo order = Common.BuildOrder(); 33 orderBusiness.LoadOrder(order); // 防止首次连接的开销 34 35 startMili = System.currentTimeMillis(); 36 OrderInfo returnOrder = null; 37 for (int i = 0; i < loop; i++) { 38 returnOrder = orderBusiness.LoadOrder(order); 39 } 40 endMili = System.currentTimeMillis(); 41 System.out.println("单个pojo 平均传输耗时为:" + ((endMili - startMili) / (float) loop) + "毫秒 ,返回对象BillNumber:" + returnOrder.getBillNumber()); 42 } catch (Exception ex) { 43 System.out.println("单个pojo 测试失败!"); 44 //ex.printStackTrace(); 45 } 46 47 // pojo集合 (100) 48 try { 49 List<OrderInfo> orderList = Common.BuildOrderList(); 50 startMili = System.currentTimeMillis(); 51 List<OrderInfo> returnOrderList = null; 52 for (int i = 0; i < loop; i++) { 53 returnOrderList = orderBusiness.LoadOrders(orderList); 54 } 55 endMili = System.currentTimeMillis(); 56 System.out.println("pojo集合 (100) 平均传输耗时为:" + ((endMili - startMili) / (float) loop) + "毫秒 ,返回记录数:" + returnOrderList.size()); 57 } catch (Exception ex) { 58 System.out.println("pojo集合 (100) 测试失败!"); 59 } 60 61 // 1K String 62 try { 63 String str1k = Common.Build1KString(); 64 startMili = System.currentTimeMillis(); 65 String returnStr1k = null; 66 for (int i = 0; i < loop; i++) { 67 returnStr1k = orderBusiness.SendStr(str1k); 68 } 69 endMili = System.currentTimeMillis(); 70 System.out.println("1K String 平均传输耗时为:" + ((endMili - startMili) / (float) loop) + "毫秒,返回字符长度:" + returnStr1k.length()); 71 } catch (Exception ex) { 72 System.out.println("1K String 测试失败!"); 73 } 74 75 // 100K String 76 try { 77 String str100K = Common.Build100KString(); 78 startMili = System.currentTimeMillis(); 79 String returnStr100k = null; 80 for (int i = 0; i < loop; i++) { 81 returnStr100k = orderBusiness.SendStr(str100K); 82 } 83 endMili = System.currentTimeMillis(); 84 System.out.println("100K String 平均传输耗时为:" + ((endMili - startMili) / (float) loop) + "毫秒,返回字符长度:" + returnStr100k.length()); 85 } catch (Exception ex) { 86 System.out.println("100K String 测试失败!"); 87 } 88 89 // 1M String 90 try { 91 String str1M = Common.Build1MString(); 92 startMili = System.currentTimeMillis(); 93 String returnStr1M = null; 94 for (int i = 0; i < loop; i++) { 95 returnStr1M = orderBusiness.SendStr(str1M); 96 } 97 endMili = System.currentTimeMillis(); 98 System.out.println("1M String 平均传输耗时为:" + ((endMili - startMili) / (float) loop) + "毫秒,返回字符长度:" + returnStr1M.length()); 99 } catch (Exception ex) { 100 System.out.println("1M String 测试失败!"); 101 } 102 103 System.out.println("all test done!"); 104 } 105 }
3、测试数据耗时记录
A、dubbo 协议、netty 传输、hessian2 序列化
<dubbo:protocol name="dubbo" server="netty" port="30001" serialization="hessian2" />
单个POJO | 0.958毫秒 |
POJO集合 (100) | 1.438毫秒 |
1K String | 0.68毫秒 |
100K String | 4.262毫秒 |
1M String | 32.473毫秒 |
B、dubbo 协议、netty 传输、dubbo 序列化
单个POJO | 1.45毫秒 |
POJO集合 (100) | 3.42毫秒 |
1K String | 0.94毫秒 |
100K String | 4.35毫秒 |
1M String | 27.92毫秒 |
C、dubbo 协议、netty 传输、java 序列化
<dubbo:protocol name="dubbo" server="netty" port="30001" serialization="java" />
单个POJO | 1.91毫秒 |
POJO集合 (100) | 4.48毫秒 |
1K String | 1.0毫秒 |
100K String | 3.3毫秒 |
1M String | 18.09毫秒 |
D、RMI 协议、netty 传输、java 序列化
<dubbo:protocol name="rmi" server="netty" port="1099" serialization="java" />
单个POJO | 1.63毫秒 |
POJO集合 (100) | 5.15毫秒 |
1K String | 0.77毫秒 |
100K String | 2.15毫秒 |
1M String | 15.21毫秒 |
E、RMI 协议、netty 传输、hessian2 序列化
单个POJO | 1.63毫秒 |
POJO集合 (100) | 5.12毫秒 |
1K String | 0.76毫秒 |
100K String | 2.13毫秒 |
1M String | 15.11毫秒 |
F、Hessian协议、servlet(tomcat容器)、hessian2 序列化
单个POJO | 1.6毫秒 |
POJO集合 (100) | 5.98毫秒 |
1K String | 1.88毫秒 |
100K String | 5.52毫秒 |
1M String | 39.87毫秒 |
G、WebService协议、servlet(tomcat容器)、SOAP序列化
<dubbo:protocol name="webservice" port="8080" server="servlet" />
单个POJO | 7.4毫秒 |
POJO集合 (100) | 34.39毫秒 |
1K String | 6.0毫秒 |
100K String | 7.43毫秒 |
1M String | 34.61毫秒 |
4、性能对比
六、多线程测试
1、由于测试机器配置较低,为了避免达到CPU瓶颈,测试设定服务消费方Consumer并发10个线程,每个线程连续对远程方法执行5次调用,服务提供方设置允许最大连接数100个,同时5个连接并行执行,超时时间设置为5000ms,要求所有事务都能正确返回没有异常,统计包含首次建立连接的消耗时间。
2、服务消费方测试代码
3、测试数据耗时记录
A、dubbo 协议、netty 传输、hessian2 序列化
单个POJO | 1165毫秒 |
POJO集合 (100) | 1311毫秒 |
1K String | 1149毫秒 |
100K String | 1273毫秒 |
1M String | 2141毫秒 |
B、dubbo 协议、netty 传输、dubbo 序列化
<dubbo:protocol name="dubbo" server="netty" port="30001" serialization="dubbo" />
单个POJO | 1220毫秒 |
POJO集合 (100) | 1437毫秒 |
1K String | 1145毫秒 |
100K String | 1253毫秒 |
1M String | 2065毫秒 |
C、dubbo 协议、netty 传输、java 序列化
<dubbo:protocol name="dubbo" server="netty" port="30001" serialization="java" />
单个POJO | 1188毫秒 |
POJO集合 (100) | 1401毫秒 |
1K String | 1123毫秒 |
100K String | 1227毫秒 |
1M String | 1884毫秒 |
D、RMI 协议、netty 传输、java 序列化
<dubbo:protocol name="rmi" server="netty" port="1099" serialization="java" />
单个POJO | 1751毫秒 |
POJO集合 (100) | 1569毫秒 |
1K String | 1766毫秒 |
100K String | 1356毫秒 |
1M String | 1741毫秒 |
E、RMI 协议、netty 传输、hessian2 序列化
<dubbo:protocol name="rmi" server="netty" port="1099" serialization="hessian2" />
单个POJO | 1759毫秒 |
POJO集合 (100) | 1968毫秒 |
1K String | 1239毫秒 |
100K String | 1339毫秒 |
1M String | 1736毫秒 |
F、Hessian协议、servlet、hessian2 序列化
<dubbo:protocol name="hessian" port="8080" server="servlet" serialization="hessian2" />
单个POJO | 1341毫秒 |
POJO集合 (100) | 2223毫秒 |
1K String | 1800毫秒 |
100K String | 1916毫秒 |
1M String | 2445毫秒 |
G、WebService协议、servlet、SOAP序列化
<dubbo:protocol name="webservice" port="8080" server="servlet" />
单个POJO | 1975毫秒 |
POJO集合 (100) | 2768毫秒 |
1K String | 1894毫秒 |
100K String | 2098毫秒 |
1M String | 2887毫秒 |
4、性能对比
七、性能分析
测试过程中尽管考虑了非常多的影响因素,但仍然有很多局限性,包括连接数限制、并发量、线程池策略、Cache、IO、硬件性能瓶颈等等因素,而且各自的适用场景不同,测试结果仅供参考。
从单线程测试结果可以看出,dubbo协议采用NIO复用单一长连接更适合满足高并发小数据量的rpc调用,而在大数据量下的传输性能并不好,建议使用rmi协议,多线程测试中dubbo协议对小数据量的rpc调用同样保持优势,在大数据量的传输中由于长连接的原因对比rmi协议传输耗时差距并不明显,这点同样验证了上述观点。关于数据的序列化方式选择需要考虑序列化和反序列化的效率问题,传输内容的大小,以及格式的兼容性约束,其中hessian2作为duobb协议下的默认序列化方式,推荐使用。
http://www.mamicode.com/info-detail-494195.html
相关推荐
Dubbo作为阿里巴巴开源的一款高性能、轻量级的RPC框架,广泛应用于服务治理领域。而Netty则是一款高效的异步事件驱动网络应用框架,常用于构建高并发、高性能的网络服务器。本项目结合两者,利用Netty实现了Dubbo的...
总之,基于Dubbo框架的分布式视频网站架构设计,不仅能够为视频网站提供可靠、安全和稳定的服务,还能满足网站业务快速发展的需求,实现架构的灵活扩展和高效运行。这对于中大型网站来说,是一次架构设计上的重要...
【标题】"dubbo框架的代码" Dubbo是阿里巴巴开源的一款高性能、轻量级的Java分布式服务框架,它旨在提高微服务架构中的服务治理效率,促进服务间的通信和协同。Dubbo的核心特性包括服务发现、服务调用、负载均衡、...
【Dubbo框架技术开发文档】 Dubbo是一款由阿里巴巴开源的高性能、轻量级的Java RPC框架,它专注于服务治理,提供了服务注册、发现、调用、负载均衡、容错、监控等一系列完整的服务治理方案。本文档将深入探讨Dubbo...
Dubbo是一款由阿里巴巴开源的高性能Java RPC框架,它在分布式系统中起到了服务调用的核心作用。RPC(Remote Procedure Call)允许一个程序调用另一个在不同网络计算机上的程序,就像调用本地函数一样简单。Dubbo的...
本资料包旨在帮助学习者深入理解并实践Dubbo框架,特别包含了手写示例代码,注释清晰,便于理解和应用。 1. **RPC原理与Dubbo的角色** RPC(Remote Procedure Call)是一种进程间通信方式,允许程序调用另一个地址...
### 基于SpringCloud的微服务实战案例与Dubbo微服务开发基础框架解析 ...以上就是对“基于SpringCloud的微服务实战案例-基于Dubbo的微服务开发基础框架”的详细介绍,希望能为相关领域的学习和实践提供有价值的参考。
4. **协议(Protocol)**:Dubbo支持多种通信协议,如RPC协议(dubbo)、HTTP协议(rest、hessian等)。在实际项目中,通常选择性能较好的dubbo协议。 5. **Spring整合**:为了简化配置和管理,我们可以利用Spring...
Dubbo是中国阿里巴巴公司开源的一款高性能、轻量级的Java服务治理框架,它主要为企业级应用提供RPC(远程过程调用)服务。这个压缩包文件包含了关于Dubbo分布式框架的学习资料和实例,对于深入理解并掌握Dubbo有极大...
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了面向接口的远程方法调用能力,使得服务消费方可以像调用本地方法一样调用远程服务,极大地简化了分布式系统开发。本项目示例主要展示了如何配置和实现基于...
在IT行业中,分布式服务框架是构建大型互联网应用的关键技术之一,Dubbo作为阿里巴巴开源的一款高性能、轻量级的Java RPC框架,被广泛应用于服务治理。本篇将详细讲解如何利用Dubbo结合Zookeeper来实现Web服务...
【描述】简单明了地表明了该项目是基于Dubbo的,暗示了它可能包含了一系列配置、样例代码或者应用,用于演示如何在实际开发中使用Dubbo作为RPC框架。RPC(Remote Procedure Call)是一种使程序能够调用另一个地址...
【Dubbo分布式服务框架】是阿里巴巴开源的一款高性能、轻量级的Java RPC框架,它提供了丰富的服务治理功能,包括服务注册、服务发现、负载均衡、容错机制等,旨在提高微服务架构下的服务调用效率和系统稳定性。Dubbo...
其次,DUBBO支持多种通信协议,如基于TCP的RPC(远程过程调用)协议,以及基于HTTP的RESTful协议。RPC协议提供了低延迟、高效率的直接服务调用方式,而RESTful协议则便于前端和移动端的直接交互。此外,DUBBO还支持...
- **多种通信协议**: rpcx不仅支持JSON-RPC,还支持二进制编码的protobuf,甚至可以自定义编码方式,提供多样的数据传输选择。 - **服务治理**: 基于etcd或zookeeper等服务注册与发现机制,实现服务的自动注册、...
Dubbo是阿里巴巴开源的高性能、轻量级的Java RPC框架,适用于大型分布式系统的服务治理。在这个电商系统中,Dubbo作为服务化的核心组件,负责服务的注册与发现、负载均衡、调用监控、容错处理等功能。它允许将复杂的...
【Dubbo+Zookeeper的RPC分布式集群服务系统】是一个基于Java开发的高性能、轻量级的服务框架,结合Zookeeper作为注册中心实现远程过程调用(RPC)的分布式集群服务。Dubbo是阿里巴巴开源的分布式服务框架,而...
而当我们谈论"jmeter测试dubbo请求"时,这意味着我们要利用JMeter对基于Dubbo框架的服务进行压力和负载测试。 Dubbo是阿里巴巴提供的一款高性能、轻量级的Java RPC框架,它使得服务调用变得简单,能有效提升分布式...
Dubbo服务框架是阿里巴巴开源的一款高性能、轻量级的Java RPC框架,主要用于构建微服务架构。版本v3.1.10带来了许多增强特性和优化,使得它在现代分布式系统中的应用更加广泛和稳定。这个压缩包包含了Dubbo 3.1.10的...
1. **Dubbo框架**:Dubbo是一个基于Java的RPC框架,它提供了服务发现、注册、调用、负载均衡等功能,旨在提高微服务架构中的服务间通信效率。Dubbo支持多种协议,如Dubbo协议、RMI、HTTP等,并且可以与其他服务治理...