文章里有一些关于Java网络通信的题目,翻出几年前的一篇文章再给大伙看看,这应该算是怎么写一个高性能RPC框架的还不错的实践,感兴趣的其实也可以自己去写个玩玩,这个过程会是学到很多东西的好方法。

下面文章写于2011年。

McQueenRPC(代码在github上)每秒支撑的请求数上升了好几倍,测试结果的演变为:

37k

–> 56k –> 65k –> 88k –> 93k –> 143k –> 148k –> 153k –> 160k –> 163k –>

168k

以上测试结果为在100并发、100 request byte、100 response byte以及单连接下的背景下得出的,在这篇blog中来分享下这个框架所做的一些优化动作,希望能给编写rpc框架或使用netty的同学们一点点帮助,也希望得到高手们更多的指点。

1、37k –> 56k

由于目前大部分的NIO框架采用的均为1个socket io线程处理多个连接的io事件,如果io线程时间占用太长的话,就会导致收到的响应处理的比较慢的现象,这步优化就是针对反序列化过程占用io线程而做的,采用的方法即为在读取流时仅根据长度信息把所有的bytes都读好,然后直接作为收到的信息返回给业务线程,业务线程在进行处理前先做反序列化动作,感兴趣的同学可以看看McQueenRPC中:NettyProtocolDecoder,以及NettyServerHandler。

2、56k –> 65k

在测试的过程中,发现YGC的耗时比较长,在咨询了sun的人后告诉我主要是由于有旧生代的数据结构引用了大量新生代对象造成的,经过对程序的分析,猜测是benchmark代码本身用于记录请求响应时间信息的ConcurrentLinkedQueue造成的,在某超级大牛的指示下,换成了在每个线程中用数组的方式,按区间来记录响应时间信息等,

感兴趣的同学可以看看McQueenRPC中

SimpleProcessorBenchmarkClientRunnable

3、65k –> 88k

在某超级大牛的分析下,发现目前的情况下io线程的上下文切换还是比较频繁,导致io线程处理效率不够高,默认情况下,NIO框架多数采用的均为接到一个包后,将这个包交由反序列化的处理器进行处理,对于包中有多个请求信息或响应信息的情况,则采用一个一个通知的方式,而rpc框架在接到一个请求或响应对象时的做法通常是唤醒等待的业务线程,因此对于一个包中有多个请求或响应的状况就会导致io线程需要多次唤醒业务线程,这个地方改造的方法是nio框架一次性的将包中所有的请求或响应对象通知给业务线程,然后由业务线程pipeline的去唤醒其他的业务线程,感兴趣的同学可以看看McQueenRPC中:NettyProtocolDecoder,以及NettyClientHandler。

4、88k –> 93k

这步没什么可说的,只是多支持了hessian序列化,然后这个结果是用hessian序列化测试得出的,注意的是hessian不要使用3.1.x或3.2.x版本,这两个系列的版本性能极差,建议使用

hessian 4.0.x版本

5、93k –> 143k

在到达93k时,看到测试的结果中有不少请求的响应时间会超过10ms,于是用btrace一步一步跟踪查找是什么地方会出现这种现象,后来发现是由于之前在确认写入os send buffer时采用的是await的方式,而这会导致需要等待io线程来唤醒,增加了线程上下文切换以及io线程的负担,但这个地方又不能不做处理,后来就改造成仅基于listener的方式进行处理,如写入失败会直接创建一个响应对象,这次改造后效果非常明显,感兴趣的同学可以看看McQueenRPC中:NettyClient。

6、143k –> 148k

这步是在@killme2008 的指点下,将

tcpNoDelay

设置为了

false

,但这个设置不适用于低压力的情况,在10个线程的情况下tps由

3w

降到了

2k

,因此tcpNoDelay这个建议还是设置成true。

7、148k –> 153k

这步没什么可说的,只是多支持了protobuf序列化,这个结果是用protobuf序列化测试得出的,之前还测试过下@bnu_chenshuo 写的一个protorpc,是基于protobuf的rpc加上netty实现的,结果也很强悍,测试出来是149k,看来protobuf的rpc也是有不少值得学习的地方的。

8、153k –> 160k

server接到消息的处理过程也修改成类似client的pipeline机制,同时将之前获取协议处理器和序列化/反序列化的处理器的地方由map改成了数组,具体可以参考NettyServerHandler、ProtocolFactory和Codecs。

9、160k –> 163k

Grizzly的leader对grizzly部分的代码做了很多的修改,结果创造了目前rpc benchmark的最高纪录:163k。

10、163k –> 168k

@minzhou 对McQueenRPC的代码进行了优化,将之前在Decoder中做的构造String对象的部分挪到了业务线程中,于是TPS也有了一定的上升,感谢。

上面就是到目前为止的所有优化动作,其中的很多我估计高手的话是不会犯错的,我走的弯路多了些,总结来说rpc框架的优化动作为:

尽可能减少io线程的占用时间,把能做的事都挪到别的线程里去做;

尽可能减少线程上下文切换;

尽可能使用高效的序列化/反序列化。

本文虽然写于十年前,但对于同类问题处理,其方法仍然有参考意义。

往期推荐:

……

技术琐话

以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理。

java分布式开发 毕玄_阿里毕玄:RPC 框架优化之路,从 37k 到 168k相关推荐

  1. java安卓开发 快速入门_安卓程序员如何快速入门后端开发常识

    首先,对于安卓开发人员来说,学习一下后端开发知识是有必要的,一方面可以拓展自身的知识面,另一方面也可以推动自己走向全栈程序员发展路线,在云计算时代,全栈程序员的发展空间会更大一些. 相对来说,安卓程序 ...

  2. java分布式部署的优点_什么是分布式系统!以及分布式系统架构的优缺点!

    现在的架构很多,各种各样的,如高并发架构.异地多活架构.容器化架构.微服务架构.高可用架构.弹性化架构等,还有和这些架构相关的管理型的技术方法,如 DevOps.应用监控.自动化运维.SOA 服务治理 ...

  3. python实现rpc框架_使用Python实现RPC框架

    前言 本文将会使用Python实现一个最简单的RPC框架,玩具向,不具有实用意义,但可以让你清醒的理解RPC框架的几个组成部分,只是比看Python自带的xmlrpc清晰. 本文需要一点Python ...

  4. 安排,谷粒商城java分布式开发基础篇高级篇与高可用集群架构篇2020

    来源: 来自网络,如侵权请告知博主删除????. 仅学习使用,请勿用于其他- 最近有小伙伴管我要分布式这类的项目,还有一些要商城的,还有要springboot,springcloud,k8s等,几乎涵 ...

  5. java后端开发工程师笔试_后端开发工程师面试参考

    为什么要写这篇文章 后端开发工程师的知识体系大而杂,从Java基础到算法.数据库.操作系统.网络.中间件.系统设计等都可以理解为后端的射程.下定决心开始准备面试时,可谓是千头万绪无从下手.我的开始源于 ...

  6. java web开发学习手册_【Java手册】Java开发手册_华山版(2019.06)

    版本号:1.5.0 更新日期:2019.06.19 制定团队:阿里巴巴与Java社区开发者 更新亮点:华山版,新增21条设计规约,修改描述112处,完善若干处示例 2017年春天,<阿里巴巴Ja ...

  7. 毕马威_【毕马威快讯】毕马威发布个人信息保护法(草案)概览

    内容提要 Summary 2020年10月21日,中国人大网公布<中华人民共和国个人信息保护法(草案)>(下称"个保法草案")全文,并对其公开征求意见. On Octo ...

  8. Java客户端开发是什么_客户端桌面应用一般是用什么技术开发的?

    JAVA GUI 觉得java是最好学的语言.也是像我这种非科班出生的,踏入码农行业的敲门砖(看C c++ 学了一年,也就hello word,会写几个demo界面). Windows桌面应用程序开发 ...

  9. 学会java足够开发app吗_请问如何两个月内在不懂java 的情况下学会开发app?

    泻药 问题让我有点恍惚: 1.首先Java不是开发APP的唯一语言,Android可以用Java开发,iOS用的是OC或者Swift. 2.开发app的方法不止原生开发这一种,有混合开发(即原生+we ...

最新文章

  1. Android SharedPreferences 详解 源码解析
  2. 软件测试 图覆盖,软件测试(四)——图覆盖
  3. 多索引表 (1)boost::multi_index多索引容器
  4. arm嵌入式linux应用实例开发pdf,零点起步——ARM嵌入式Linux应用开发入门一书的源代码...
  5. Little Elephant and Shifts(CF-220C)
  6. AAA Password Expiry in Cisco IOS Easy***
  7. linux tcp 阻塞时间,TCP的阻塞和重传机制
  8. linux activemq修改端口号,linux下 activemq集群配置
  9. 《C语言及程序设计》实践参考——间隔选职工
  10. MVC中将list转化成json 并处理时间格式
  11. 【安卓笔记】是否执行测试服务
  12. 520 miix 小兵 黑苹果_黑苹果资源
  13. python进行数据抽取_python中的数据抽取
  14. iphone11主卡在上还是下
  15. 比google earth还好的实景地图
  16. 浩辰CAD 2019 v190128官方免费版
  17. 頑健なJavaプログラムの書き方
  18. xpage 传参_一个轻量级的Android路由框架,基于ARouter上进行改良,优化Fragment的使用,可结合XPage使用。...
  19. stdin,stderr,stdout
  20. 【FHQ Treap】洛谷P5055 【模板】可持久化文艺平衡树

热门文章

  1. 毕业生基本要素之计算机水平,2017年非上海生源应届高校毕业生进沪就业评分办法...
  2. 浅析notifyDataSetChanged内部工作流程
  3. linux安装oracle12C客户端(适用于18C客户端和19C客户端)
  4. 理解method(实例方法), staticmethod(静态方法)和classmethod(类方法)的区别
  5. 【语音识别】基于matlab GUI动态时间规整算法(RTW)语音识别系统【含Matlab源码 341期】
  6. 【2】logging: requests.packages.urllib3.connectionpool
  7. 机器学习中的数学——常用概率分布(五):高斯分布(Gaussian分布)/正态分布(Normal分布)
  8. 不出门知天下事的好网站好博客
  9. (python基础)交叉验证
  10. 揭秘现阶段二手车市场交易的现状