dubbo源码分析系列——dubbo典型协议、传输组件、序列化方式组合性能对比测试

作者:杨武兵

出处:https://my.oschina.net/ywbrj042?tab=newest&catalogId=3594617


前言

Dubbo作为一个扩展能力极强的分布式服务框架,在实现rpc特性的时候,给传输协议、传输框架和序列化方式提供了多种扩展实现,供开发者根据实际场景进行选择。

1、支持常见的传输协议:RMI、Dubbo、Hessain、WebService、Http等,其中Dubbo和RMI协议基于TCP实现,Hessian和WebService基于HTTP实现。

2、传输框架:Netty、Mina、grizzly以及基于servlet等方式。

3、序列化方式:Hessian2、dubbo、JSON( fastjson 实现)、JAVA、SOAP、kryo和fst 等。

本文主要基于dubbox框架下的通讯协议进行性能测试对比。

文章模板参考了:http://www.cnblogs.com/lengfo/p/4293399.html?utm_source=tuicool&utm_medium=referral,在该文的基础上做了一些调整,测试数据是本人亲自测试的实际结果。

测试方案

基于dubbox 2.8.4框架,使用zookeeper作为注册中心,分别以单线程和多线程的方式测试以下组合。

| 分组名 | Protocol | Transporter   | Serialization     | Remark |
| A | dubbo | netty | hessian2 | |
| B | dubbo | netty | dubbo | |
| C | dubbo | netty | java | |
| D | dubbo | netty | fst |   |
| E | dubbo | netty | kryo |   |
| F | dubbo | mina | hessian2 |   |
| G | rmi | netty | java | |
| H | rmi | netty | hessian2 | |
| I | Hessian | servlet | hessian2 | Hessian,基于tomcat8.0嵌入式容器      |
| J | WebService  | servlet | SOAP | CXF,基于tomcat8.0嵌入式容器 |
| K | http | servlet | json | 基于tomcat8.0嵌入式容器 |

测试环境

本次测试是所有组件都部署在同一台PC机上进行的,包括zookeeper,消费者和生产者都是在本机上。

机器的配置如下:

内存12G;

CPU是intel i5 2.5ghz 4核;

操作系统Windows visita6.1;

jdk1.6.0.25和jdk1.7.0_79;

JVM配置是默认值,最大堆64M,

传输测试数据

1、单POJO对象,嵌套复杂集合类型

2、POJO集合,包含100个单POJO对象

3、1K字符串

4、100K字符串

5、1M字符串 

服务接口和实现

1、服务接口相关代码: 

public interface DemoService {
    public Object sendRequest(Object requestObject);
}

2、服务实现相关代码,测试数据在服务器端不做任何处理原样返回:

public class DemoServiceImpl implements DemoService{
    ResponseObject responseObject = new ResponseObject(100);

    public Object sendRequest(Object request) {
        return request;
    }
}

3、测试框架介绍

本文是基于dubbo自带的benchmark性能测试框架进行测试的,对该框架做了简单的调整和修改,框架代码见:https://github.com/dangdangdotcom/dubbox/tree/master/dubbo-test/dubbo-test-benchmark

单线程测试

1、测试仅记录rpc调用时间,测试数据的读取组装以及首次建立连接等相关耗时时间不作统计,循环执行60秒钟取平均响应时间值。

2、服务消费方测试代码

输入复杂POJO测试代码

private static BidRequest request = new BidRequest();
    private static int size = 100;
    private static List<BidRequest> requests = new ArrayList<BidRequest>();

    static{
        request.setId("ssss");
        Geo geo = new Geo();
        geo.setCity("beijing");
        geo.setCountry("china");
        geo.setLat(1.0f);
        geo.setLon(5.3f);

        Device device = new Device();
        device.setLang("中文");
        device.setOs("windows 7");
        device.setVersion("1.0.0");
        device.setModel("dddddd");
        device.setGeo(geo);

        request.setDevice(device);

        List<Impression> impressions = new ArrayList<Impression>();
        for(int i=0; i<3; i++){
            Impression impression = new Impression();
            impression.setId("2333"+i);
            impression.setBidFloor(2223.3333d);
            impressions.add(impression);
        }
        request.setImpressions(impressions);

        for(int i=0; i<size; i++){
            requests.add(request);
        }
    }

 @SuppressWarnings({ "unchecked"})
    @Override
    public Object invoke(ServiceFactory serviceFactory) {
        DemoService demoService = (DemoService) serviceFactory.get(DemoService.class);
        Object result = demoService.sendRequest(requests);
        return result;
    }

输入字符串测试代码

private static String message = null;
    private static int length = 1024000;
    static{
        message = new String(new byte[length]);
    }

public Object invoke(ServiceFactory serviceFactory) {
        DemoService demoService = (DemoService) serviceFactory.get(DemoService.class);
        Object result = demoService.sendRequest(requestObject);
        return result;
    }

3、测试数据耗时记录

A、dubbo 协议、netty 传输、hessian2 序列化

jdk1.6测试数据

单个POJO 0.369ms
POJO集合 (100) 3.326ms
1K String 0.354ms
100K String 17.804ms
1M String 154.178ms

jdk1.7测试数据

单个POJO 0.195ms
POJO集合 (100) 1.207ms
1K String 0.203ms
100K String 4.901ms
1M String 47.691ms

B、dubbo 协议、netty 传输、dubbo 序列化

 

jdk1.6测试数据

单个POJO 0.345ms
POJO集合 (100) 6.663ms
1K String 0.325ms
100K String 17.756ms
1M String 128.241ms

jdk1.7测试数据

单个POJO 0.203ms
POJO集合 (100) 2.47ms
1K String 0.193ms
100K String 3.917ms
1M String 36.186ms

C、dubbo 协议、netty 传输、java 序列化

jdk1.6测试数据

单个POJO 0.541ms
POJO集合 (100) 4.194ms
1K String 0.391ms
100K String 26.561ms
1M String 151.337ms

jdk1.7测试数据

单个POJO 0.375ms
POJO集合 (100) 1.839ms
1K String 0.237ms
100K String 5.691ms
1M String 54.462ms

D、dubbo 协议、netty 传输、fst序列化

jdk1.6测试数据

单个POJO 0.273ms
POJO集合 (100) 0.768ms
1K String 0.31ms
100K String 20.048ms
1M String 353.594ms

jdk1.7测试数据

单个POJO 0.187ms
POJO集合 (100) 0.429ms
1K String 0.281ms
100K String 2.861ms
1M String 30.599ms

E、dubbo 协议、netty 传输、kryo序列化

jdk1.6测试数据

单个POJO 3.087ms
POJO集合 (100) 3.749ms
1K String 3.017ms
100K String 33.283ms
1M String 353.851ms

jdk1.7测试数据

单个POJO 2.767ms
POJO集合 (100) 2.869ms
1K String 2.636ms
100K String 5.804ms
1M String 33.501ms

F、dubbo 协议、mina 传输、hessian2序列化

jdk1.6测试数据

单个POJO 0.378ms
POJO集合 (100) 3.47ms
1K String 6002.945ms
100K String 6061.22ms
1M String 5067.535ms

jdk1.7测试数据

单个POJO 0.213ms
POJO集合 (100) 6004.22ms
1K String 6003.739ms
100K String 6013.998ms
1M String 3779.117ms

G、RMI 协议、netty 传输、java 序列化 

jdk1.6测试数据

单个POJO 0.349ms
POJO集合 (100) 2.874ms
1K String 0.203ms
100K String 7.129ms
1M String 136.697ms

jdk1.7测试数据

单个POJO 0.203ms
POJO集合 (100) 1.515ms
1K String 0.138ms
100K String 3.609ms
1M String 35.188ms

H、RMI 协议、netty 传输、hessian2 序列化 

 

jdk1.6测试数据

单个POJO 0.338ms
POJO集合 (100) 2.815ms
1K String 0.196ms
100K String 8.509ms
1M String 134.098ms

jdk1.7测试数据

单个POJO 0.213ms
POJO集合 (100) 1.511ms
1K String 0.139ms
100K String 3.589ms
1M String 36.322ms

I、Hessian协议、servlet(tomcat容器)、hessian2 序列化 

用到了tomcat-embed-core-8.0.11,需要用jdk1.7以上版本,所以本次测试使用jdk1.7

 

jdk1.7测试数据

单个POJO 0.482ms
POJO集合 (100) 3.201ms
1K String 0.413ms
100K String 6.893ms
1M String 59.805ms

J、WebService协议、servlet(tomcat容器)、SOAP序列化

jdk1.7测试数据

单个POJO 0.598ms
POJO集合 (100) 0.731ms
1K String 11.603ms
100K String 71.991ms
1M String 81.596ms

H、http协议、servlet(tomcat容器)、json序列化

jdk1.7测试数据

单个POJO 0.586ms
POJO集合 (100) 2.179ms
1K String 0.722ms
100K String 6.982ms
1M String 59.848ms

4、性能对比

多线程测试

1、由于测试机器配置较低,为了避免达到CPU瓶颈,测试设定服务消费方Consumer并发10个线程,每个线程连续对远程方法执行60秒钟,超时时间设置为2000ms,要求所有事务都能正确返回没有异常。

性能分析

影响性能测试结果的因素太多了,本文只是做了非常局限的测试,测试用例覆盖率不够,测试环境和条件制约较大,因此本文的测试结果绝对是仅供参考。不能完全信任本文的测试数据和结论。

通过上述的对比测试分析可以看出:

1.内部应用之间的小尺寸的对象和字符串调用的场景推荐使用dubbo+netty+fst的组合较优。fst的性能要由于hessian2。

2.rmi协议在传输大尺寸字符串对象的时候表现更优,这超出了我们一般的认知。

3.mina框架不推荐使用,则测试中的表现非常差,深层次的原因还没有深究,大量的调用超时失败,dubbo的测试报告也指出它存在一些问题,因此该框架不建议使用。

4.kryo序列化组件的性能表现较差,这与其它的测试报告的出入较大,具体原因需要深层次的探究。

5.有部分测试失败,具体原因有待考究。

6.jdk1.6 和 jdk1.7对性能测试结果差异较大,jdk1.7测试性能好于1.6. 推荐使用jdk1.7. 以dubbo协议,默认的传输组件和序列化组件为例,jdk1.7的环境下性能提升接近于90%。

赞(0) 打赏

如未加特殊说明,此网站文章均为原创,转载必须注明出处。Java 技术驿站 » dubbo源码分析系列——dubbo典型协议、传输组件、序列化方式组合性能对比测试
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

关注【Java 技术驿站】公众号,每天早上 8:10 为你推送一篇技术文章

扫描二维码关注我!


关注【Java 技术驿站】公众号 回复 “VIP”,获取 VIP 地址永久关闭弹出窗口

免费获取资源

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏