文档章节

dubbo典型协议、传输组件、序列化方式组合性能对比测试

杨武兵
 杨武兵
发布于 2016/06/13 18:03
字数 2128
阅读 3232
收藏 25

前言

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 序列化

<dubbo:protocol name="dubbo" server="netty" port="20885" serialization="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 序列化

<dubbo:protocol name="dubbo" server="netty" port="20885" serialization="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 序列化

<dubbo:protocol name="dubbo" server="netty" port="20885" serialization="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序列化

<dubbo:protocol name="dubbo" server="netty" port="20885" serialization="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序列化

<dubbo:protocol name="dubbo" server="netty" port="20885" serialization="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序列化

<dubbo:protocol name="dubbo" server="mina" port="20885" serialization="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 序列化 

<dubbo:protocol name="rmi" server="netty" port="20885" serialization="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 序列化 

<dubbo:protocol name="rmi" server="netty" port="20885" serialization="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

<dubbo:protocol name="hessian" port="20885" server="tomcat" serialization="hessian2" /> 

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序列化

<dubbo:protocol name="webservice" port="20885" server="tomcat" />

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序列化

<dubbo:protocol name="http" port="20885" server="tomcat"  serialization="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%。

 

© 著作权归作者所有

共有 人打赏支持
杨武兵

杨武兵

粉丝 255
博文 61
码字总数 123254
作品 1
昌平
架构师
私信 提问
加载中

评论(6)

杨武兵
杨武兵

引用来自“我若挽歌”的评论

你好,kryo,fst的序列化是你自己扩展的么?有相关博客可以参考下么?谢谢啦
kryo,fst是当当维护的dubbox扩展的2种序列化方式。
我若挽歌
你好,kryo,fst的序列化是你自己扩展的么?有相关博客可以参考下么?谢谢啦
杨武兵
杨武兵

引用来自“杨武兵”的评论

嗯,你好,我想应该还会有后续的,有可能的话也许会出一本《dubbo源码分析》的书也说不定,哈哈。

引用来自“yang755994”的评论

期待你的《dubbo源码分析》出版,我要买买买
已经写了前三章,可以发给你看看,可以私聊。
y
yang755994

引用来自“杨武兵”的评论

嗯,你好,我想应该还会有后续的,有可能的话也许会出一本《dubbo源码分析》的书也说不定,哈哈。
期待你的《dubbo源码分析》出版,我要买买买
杨武兵
杨武兵
嗯,你好,我想应该还会有后续的,有可能的话也许会出一本《dubbo源码分析》的书也说不定,哈哈。
祖大俊
祖大俊
不错,真是想什么,你就来什么。最近一直想研究学习dubbo源码,你的这些文章可以很好的解决我的需求,待周末,好好研读下你的系列文章。请问,dubbo源码系列文章是写完了呢?还是还有后续的?
分布式服务框架原理(一)设计和实现

分布式服务框架设计 分布式服务框架一般可以分为以下几个部分, (1)RPC基础层: 包括底层通信框架,如NIO框架、通信协议,序列化和反序列化协议, 以及在这几部分上的封装,屏蔽底层通信细...

吞吞吐吐的
2017/10/04
0
0
Dubbo使用

入门 (+) (#) 背景 (#) 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。 单...

村长大神
2016/09/18
2.1K
1
在Dubbo中开发REST风格的远程调用(RESTful Remoting)(转)

作者:沈理 文档版权:Creative Commons 3.0许可证 署名-禁止演绎 完善中…… 本文篇幅较长,因为REST本身涉及面较多。另外,本文参照Spring等的文档风格,不仅仅局限于框架用法的阐述,同时...

tantexian
2016/03/07
49
0
在Dubbo中开发REST风格的远程调用(RESTful Remoting)

作者:沈理 文档版权:Creative Commons 3.0许可证 署名-禁止演绎 完善中…… 本文篇幅较长,因为REST本身涉及面较多。另外,本文参照Spring等的文档风格,不仅仅局限于框架用法的阐述,同时...

tantexian
2016/03/07
551
0
架构师之路-在Dubbo中开发REST风格的远程调用

概述 dubbo支持多种远程调用方式,例如dubbo RPC(二进制序列化 + tcp协议)、http invoker(二进制序列化 + http协议,至少在开源版本没发现对文本序列化的支持)、hessian(二进制序列化 ...

小红牛
2017/10/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

zookeeper和HBASE总结

zookeeper快速上手 zookeeper的基本功能和应用场景 zookeeper的整体运行机制 zookeeper的数据存储机制 数据存储形式 zookeeper中对用户的数据采用kv形式存储 只是zk有点特别: key:是以路径...

瑞查德-Jack
45分钟前
1
0
Oracle 查询时间在当天的数据

要实现这个功能需要用到trunc这个函数对时间的操作select trunc(sysdate) from dual --2014-12-27 今天的日期为2014-12-27select trunc(sysdate, 'mm') from dual --2014-12-1 ......

覃光林
46分钟前
1
0
阿里技术专家详解 Dubbo 实践,演进及未来规划

作者:曹胜利 链接:https://www.infoq.cn/article/IwZCAp3jo_H5fJFbWOZu?utm_source=tuicool&utm_medium=referral Dubbo 整体介绍 Dubbo 是一款高性能,轻量级的 Java RPC 框架。虽然它是以...

Java干货分享
50分钟前
1
0
深入解读阿里云数据库POLARDB核心功能物理复制技术

日志是数据库的重要组成部份,按顺序以增量的方式记录了数据库上所有的操作,日志模块的设计对于数据库的可靠性、稳定性和性能都非常重要。 可靠性方面,在有一个数据文件的基础全量备份后,...

阿里云官方博客
53分钟前
1
0
Python数据科学环境:Anaconda 了解一下

几乎所有的 Python 学习者都遇到过“安装”方面的问题。这些安装问题包括 Python 自身环境的安装、第三方模块的安装、不同版本的切换,以及不同平台、版本间的兼容问题等。当你因为这些问题而...

crossin
54分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部