First, preface
The Dubbo RPC Service Framework supports rich transport protocols, serialization methods, and other communication-related configurations and extensions. Dubbo the process of executing an RPC request is roughly as follows: the consumer (Consumer) performs an RPC request to the registry (Registry), the registry assigns the service URL and routes to the specific service provider (Provider), and the consumer and service provider establish a network connection, The service provider creates a connection pool object locally and provides remote services, maintains a connection for long connection type protocols (such as the Dubbo Protocol), reduces handshake authentication, avoids the performance overhead of frequent setup and disconnection during calls, and maintains long connections that require heartbeat packet delivery. So maintaining a connection for a service that is not frequently invoked can also be consumed. For more information about Dubbo, please refer to the official documentation (http://alibaba.github.io/dubbo-doc-static/Home-zh.htm).
1, support the Common transport protocol: RMI, Dubbo, Hessain, WebService, HTTP, etc., wherein the Dubbo and RMI protocol based on TCP implementation, Hessian and WebService based on the HTTP implementation.
2, Transmission framework: Netty, Mina, and based on servlet and other methods.
3, Serialization mode: Hessian2, Dubbo, JSON (Fastjson implementation), JAVA, SOAP and so on.
This paper is based on the communication protocol under the Dubbo framework for performance testing and comparison.
Second, the test plan
Based on the Dubbo 2.5.3 Framework, the following scenarios are tested in single-threaded and multithreaded ways, using zookeeper as the Dubbo Service registry:
|
Protocol |
Transporter |
Serialization |
Remark |
A |
Dubbo Protocol |
Netty |
Hessian2 |
|
B |
Dubbo Protocol |
Netty |
Dubbo |
|
C |
Dubbo Protocol |
Netty |
Java |
|
D |
RMI protocol |
Netty |
Java |
|
E |
RMI protocol |
Netty |
Hessian2 |
|
F |
Hessian protocol |
Servlet |
Hessian2 |
Hessian, based on the Tomcat container |
G |
WebService protocol |
Servlet |
Soap |
CXF, based on the Tomcat container |
Third, transmission test data
1. Single Pojo object, nested complex collection type
2, Pojo collection, contains 100 single Pojo objects
3, 1K string
4, 100K string
5, 1M string
Iv. Service Interface and implementation
1, the Service Interface related code:
1 package ibusiness; 2 3 import java.util.List; 4 5 import model.*; 6 7 public interface Ibusinessorder { 8 public String S ENDSTR (String str); 9 Public list<orderinfo> loadorders (list<orderinfo> orders), one public OrderInfo Loadorder ( OrderInfo order); 13}
2, the service implementation of the relevant code, test data on the server side does not do any processing is returned:
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) {One return str;12 }13, public list<orderinfo> loadorders (List <OrderInfo> orders) { orders;16 }17 OrderInfo Loadorder (OrderInfo order) {19 return order;20 } 21}
View Code
Five, single-threaded test
1, the test only records the RPC call time, test data reading assembly and the first time to establish a connection time-consuming not statistics, cyclic execution 100 averaging.
2. Service consumer Test Code
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.*; Ten import model.*; public class Program {public static void main (string[] args) throws Exception {Applicationc Ontext CTX = new Filesystemxmlapplicationcontext ("Src//applicationcontext.xml"); Ibusinessorder orderbusiness = (ibusinessorder) ctx.getbean ("orderbusiness"); +//EchoService EchoService = (echoservice) orderbusiness; //String status = EchoService. $echo ("OK"). toString (); /if (!status.equals ("OK")) {+//System.out.println ("Orderbusiness Out of service!"); 22// Return System.out.println ("Orderbusiness in service!") and/or else {+///}-Lon G Startmili, ENDMIli int loop = 100; 29 30//single Pojo try {OrderInfo order = Common.buildorder (); orderbusine Ss. Loadorder (order); The overhead of preventing the first connection is Startmili = System.currenttimemillis (); OrderInfo returnorder = null; PNS for (int i = 0; I < loop; i++) {Returnorder = Orderbusiness.loadorder (order); 39 } Endmili = System.currenttimemillis (); System.out.println ("Single Pojo average transfer time is:" + ((Endmili-startmili)/(float) loop) + "milliseconds, return object billnumber:" + RET Urnorder.getbillnumber ()); (Exception ex) {System.out.println ("single Pojo test failed!");//ex.printstacktrace (); Pojo///Set (+)-try {list<orderinfo> orderlist = Common.build OrderList (); Startmili = System.currenttimemillis (); Wuyi list<orderinfo> returnorderlist = null for (int i = 0; I < loop; i++) {returnorderlist = Orderbusiness.loadorders (orderlist ); Endmili = System.currenttimemillis (); System.out.println ("Pojo collection (100) Average transfer time is:" + ((Endmili-startmili)/(float) loop) + "milliseconds, return Record count:" + return Orderlist.size ()); (Exception ex) {System.out.println ("Pojo collection (100) test failed!"); 59} 60 61/ /1K string try {str1k = common.build1kstring (); Startmili = System.curre Nttimemillis (); A String of returnstr1k = null; (int i = 0; I < loop; i++) {returnstr1k = Orderbusiness.sendstr (str1k); 68 } Endmili = System.currenttimemillis (); System.out.println ("1K String average transfer time is:" + ((Endmili-startmili)/(float) loop) + "milliseconds, return character length:" + returnstr 1k.length ()); (Exception ex) {72 System.out.println ("1K String test failed!"); //100K string try {str100k = common.build100kstring (); 78 Startmili = System.currenttimemillis (); returnstr100k String = null; (int i = 0; I < loop; i++) {Bayi returnstr100k = orderbusiness.sendstr (str100k); 82 } Endmili = System.currenttimemillis (); System.out.println ("100K String average transfer time is:" + ((Endmili-startmili)/(float) loop) + "milliseconds, return character length:" + ReturnS Tr100k.length ()); (Exception ex) {System.out.println ("100K String test failed!"); 87} 88 89// 1M string try {str1m = common.build1mstring (); Startmili = System.curren Ttimemillis (); Returnstr1m String = null; 94 for (int i = 0; I < loop; i++) {returnstr1m = Orderbusiness.sendSTR (STR1M); Endmili = System.currenttimemillis (); 98 System.out.println ("1M String average transfer time is:" + ((Endmili-startmili)/(float) loop) + "milliseconds, return character length:" + returnstr 1m.length ()); (Exception ex) {System.out.println ("1M String test failed!"); 101}102 103 System.out.println ("All Test done!"); 104} 105}
View Code
3. Test data time-consuming record
A, Dubbo Protocol, Netty Transmission, HESSIAN2 serialization
<dubbo:protocol name= "Dubbo" server= "Netty" port= "30001" serialization= "hessian2"/>
Single Pojo |
0.958 ms |
Pojo Collection (100) |
1.438 ms |
1 k String |
0.68 ms |
100K String |
4.262 ms |
1M String |
32.473 ms |
B, Dubbo Protocol, Netty Transmission, Dubbo serialization
<dubbo:protocol name= "Dubbo" server= "Netty" port= "30001" serialization= "Dubbo"/>
Single Pojo |
1.45 ms |
Pojo Collection (100) |
3.42 MS |
1 k String |
0.94 ms |
100K String |
4.35 ms |
1M String |
27.92 ms |
C, Dubbo Protocol, Netty Transmission, Java serialization
<dubbo:protocol name= "Dubbo" server= "Netty" port= "30001" serialization= "java"/>
Single Pojo |
1.91 ms |
Pojo Collection (100) |
4.48 ms |
1 k String |
1.0 ms |
100K String |
3.3 ms |
1M String |
18.09 ms |
D, RMI protocol, Netty Transmission, Java serialization
<dubbo:protocol name= "rmi" server= "Netty" port= "1099" serialization= "Java"/>
Single Pojo |
1.63 ms |
Pojo Collection (100) |
5.15 ms |
1 k String |
0.77 MS |
100K String |
2.15 ms |
1M String |
15.21 MS |
E, RMI protocol, Netty Transmission, HESSIAN2 serialization
<dubbo:protocol name= "rmi" server= "Netty" port= "1099" serialization= "hessian2"/>
Single Pojo |
1.63 ms |
Pojo Collection (100) |
5.12 MS |
1 k String |
0.76 ms |
100K String |
2.13 ms |
1M String |
15.11 MS |
F, Hessian protocol, servlet (Tomcat container), hessian2 serialization
<dubbo:protocol name= "Hessian" port= "8080" server= "servlet" serialization= "hessian2"/>
Single Pojo |
1.6 ms |
Pojo Collection (100) |
5.98 ms |
1 k String |
1.88 ms |
100K String |
5.52 ms |
1M String |
39.87 ms |
G, WebService Protocol, servlet (Tomcat container), SOAP serialization
<dubbo:protocol name= "WebService" port= "8080" server= "servlet"/>
Single Pojo |
7.4 ms |
Pojo Collection (100) |
34.39 ms |
1 k String |
6.0 ms |
100K String |
7.43 ms |
1M String |
34.61 ms |
4. Performance Comparison
Six, multi-threaded test
1, because the test machine configuration is low, in order to avoid the CPU bottleneck, the test set service consumer consumer concurrent 10 threads, each thread continuously to the remote method to perform 5 calls, the service provider set allows the maximum number of connections 100, while 5 connections in parallel execution, The timeout is set to 5000ms, requiring all transactions to return correctly without exceptions, and the statistics contain the time spent on the first connection setup.
2. Service consumer Test Code
3. Test data time-consuming record
A, Dubbo Protocol, Netty Transmission, HESSIAN2 serialization
<dubbo:protocol name= "Dubbo" server= "Netty" port= "30001" serialization= "hessian2"/>
Single Pojo |
1165 ms |
Pojo Collection (100) |
1311 MS |
1 k String |
1149 MS |
100K String |
1273 MS |
1M String |
2141 MS |
B, Dubbo Protocol, Netty Transmission, Dubbo serialization
<dubbo:protocol name= "Dubbo" server= "Netty" port= "30001" serialization= "Dubbo"/>
Single Pojo |
1220 MS |
Pojo Collection (100) |
1437 MS |
1 k String |
1145 MS |
100K String |
1253 MS |
1M String |
2065 MS |
C, Dubbo Protocol, Netty Transmission, Java serialization
<dubbo:protocol name= "Dubbo" server= "Netty" port= "30001" serialization= "java"/>
Single Pojo |
1188 MS |
Pojo Collection (100) |
1401 MS |
1 k String |
1123 MS |
100K String |
1227 MS |
1M String |
1884 MS |
D, RMI protocol, Netty Transmission, Java serialization
<dubbo:protocol name= "rmi" server= "Netty" port= "1099" serialization= "Java"/>
Single Pojo |
1751 MS |
Pojo Collection (100) |
1569 MS |
1 k String |
1766 ms |
100K String |
1356 MS |
1M String |
1741 MS |
E, RMI protocol, Netty Transmission, HESSIAN2 serialization
<dubbo:protocol name= "rmi" server= "Netty" port= "1099" serialization= "hessian2"/>
Single Pojo |
1759 MS |
Pojo Collection (100) |
1968 MS |
1 k String |
1239 MS |
100K String |
1339 MS |
1M String |
1736 MS |
F, Hessian protocol, servlet, HESSIAN2 serialization
<dubbo:protocol name= "Hessian" port= "8080" server= "servlet" serialization= "hessian2"/>
Single Pojo |
1341 MS |
Pojo Collection (100) |
2223 ms |
1 k String |
1800 ms |
100K String |
1916 MS |
1M String |
2445 ms |
G, WebService protocol, servlet, SOAP serialization
<dubbo:protocol name= "WebService" port= "8080" server= "servlet"/>
Single Pojo |
1975 MS |
Pojo Collection (100) |
2768 ms |
1 k String |
1894 MS |
100K String |
2098 ms |
1M String |
2887 ms |
4. Performance Comparison
Seven, performance analysis
Although a lot of factors are considered in the testing process, there are still many limitations, including connection number limit, concurrency, thread pool policy, Cache, IO, hardware performance bottleneck and so on, and the test results are for reference only .
From the single-threaded test results, it can be seen that the Dubbo protocol using NIO multiplexing single long connection is more suitable to meet the high concurrency of small data volume of RPC calls, and in the large data volume of the transmission performance is not good, the proposed RMI protocol, multithreaded testing in the Dubbo protocol to small data volume RPC calls also maintain the advantage, This is also verified by the fact that the time lag gap between RMI protocol transmission is not obvious in the transmission of large data volumes due to long connections. The choice of serialization method for data requires consideration of the efficiency of serialization and deserialization, the size of the transmitted content, and the compatibility constraints of the format, where Hessian2 is recommended as the default serialization method under the Duobb protocol.
If there is a description of the error or inappropriate place welcome correction.
Performance test of RPC communication protocol based on Dubbo framework