Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

10 | 网络通信优化之通信协议:如何优化RPC网络通信?

刘超 2019-06-11
你好,我是刘超。今天我将带你了解下服务间的网络通信优化。
上一讲中,我提到了微服务框架,其中 SpringCloud 和 Dubbo 的使用最为广泛,行业内也一直存在着对两者的比较,很多技术人会为这两个框架哪个更好而争辩。
我记得我们部门在搭建微服务框架时,也在技术选型上纠结良久,还曾一度有过激烈的讨论。当前 SpringCloud 炙手可热,具备完整的微服务生态,得到了很多同事的票选,但我们最终的选择却是 Dubbo,这是为什么呢?

RPC 通信是大型服务框架的核心

我们经常讨论微服务,首要应该了解的就是微服务的核心到底是什么,这样我们在做技术选型时,才能更准确地把握需求。
就我个人理解,我认为微服务的核心是远程通信和服务治理。远程通信提供了服务之间通信的桥梁,服务治理则提供了服务的后勤保障。所以,我们在做技术选型时,更多要考虑的是这两个核心的需求。
我们知道服务的拆分增加了通信的成本,特别是在一些抢购或者促销的业务场景中,如果服务之间存在方法调用,比如,抢购成功之后需要调用订单系统、支付系统、券包系统等,这种远程通信就很容易成为系统的瓶颈。所以,在满足一定的服务治理需求的前提下,对远程通信的性能需求就是技术选型的主要影响因素。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(25)

  • WL
    请教老师两个问题:
    1. 在RMI的实现原理示意图中客户端的存根和服务端的骨架这两个概念是啥意思, 我感觉不太理解.
    2. 在TCP的四次挥手中, 客户端最后的TIME_WAIT状态是不是就是CLOSE的状态, 如果不是那TIME_WAIT状态是在啥时候转换成CLOSE状态的.

    作者回复: 我先回答第二个问题。

    是的,TIME_WAIT状态就是主动断开方的最后状态了。主动断开连接方之所以是TIME_WAIT状态,是担心被断开方没有收到最后的ACK,这个TIME_WAIT时间内核默认设置是2MSL(报文最大生存时间),被断开方如果超时没有收到ACK,将重新发送FIN,主动断开方收到之后又会重新发送ACK通知,重置TIME_WAIT时间。

    正常情况下,当主动断开方的TIME_WAIT状态到达了定时时间后,内核就会关闭该连接。

    第一个问题,这块文章中没有过多的介绍,我在这里再叙述下:


    Stub是client端的远程对象的代理,负责将远程对象上的方法调用转发到实际远程对象实现所在的服务器,我们的程序要通过远程调用,底层一定是套接字的字节传输,要一个对象序列化成为字节码,传输到服务器或者客户端的对端之后,再把该对象反序列化成为对应的对象,Stub承担着底层序列化、数据组装以及协议封装等工作。

    Skeleton则是server端的服务对象的代理,负责将接收解析远程调用分派到实际远程对象实现调用。Stub与Skeleton的关系以及操作是对应的关系,只有实现了java.rmi.Remote接口的类或者继承了java.rmi.Remote接口的接口,才能作为Stub与Skeleton之间通信的远程对象,Stub与Skeleton之间的通信使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信,JRMP是专为Java的远程对象制定的协议。Stub和Skeleton之间协作完成客户端与服务器之间的方法调用时的通信。


    2019-06-11
    9
  • Stalary
    老师,如果业务架构已经选择了SpringCloud,该如何优化远程调用呢,目前使用Feign,底层配置了HttpClient,发现qps一直上不去,暂时是对频繁的请求做了本地cache,但是需要订阅更新事件进行刷新

    作者回复: 可以尝试扩展其他RPC框架,例如有同学提到的Google的grpc框架,也是基于Netty通信框架实现,基于protobuf实现的序列化。

    2019-06-11
    4
  • 夏天39度
    老师,能说一下Netty是如何实现串行无锁化完成链路操作吗,怎么做到无锁化的线程切换

    作者回复: Netty中,分为Reactor主线程和Reactor从线程,主线程主要用来监听连接事件,从线程主要用来处理监听I/O事件,以及处理读写I/O操作。

    一般有其他的业务操作,我们可以在handler中创建线程池来处理。但为了减少上下文切换,我们可以在ChannelPipeline上注册handler事件,例如解码过程。一般Reactor从线程监听到读操作,会立即调用ChannelPipeline的fireChannelRead方法完成读操作,在调用完读操作之后,会检查是否有其他handler,如果有,则直接调用,不会创建新的线程。

    这种方式的好处是,不用创建新的线程,在从线程中串行化完成所有的I/O以及业务操作,减少上下文切换;坏处是,给从线程带来了一定的阻塞。

    2019-06-11
    3
  • Y丶z
    老师好,我想问下已经在线上跑的服务,序列化方式是hessian,如果直接换成Protobuf,那么consumer会报错吗?如果报错的话,如何避免这种情况发生呢?

    作者回复: 服务端和消费端重启,会走protobuf序列化

    2019-06-11
    2
  • 疯狂咸鱼
    这个Dubbo阿里可以吹很多年啊
    2019-09-14
    1
  • 风轻扬
    老师。我看到留言中有同学提到http和tcp的对比。http不是建立在tcp的基础上吗?http和tcp的关系应该怎么定义呢?

    作者回复: http是基于tcp实现的协议。如果做过Socket编程通信,你会发现两个端之间如果要实现接口通信,除了传输我们需要的请求参数和返回参数之外,我们还需要给通信定义一个协议头,单纯的tcp通信是没有协议头的,而http则是在tcp基础上定义了自己的消息头和序列化方式。http通信协议是一种短连接,也就是说通信完成之后会断开连接。

    简而言之,http是tcp的一个上层封装协议,http是基于tcp实现的。

    2019-08-13
    1
  • n88
    写http是短连接不太严谨

    作者回复: 这里纠正下,http1.0版本默认是短链接,而在http1.0以后默认是保持连接的,但只是一个单向的长连接,默认情况下保持60s

    2019-10-25
  • greekw
    老师,能讲下netty的rector 线程模型的实例,以及串行无锁化设计的原理
    2019-10-20
  • yunfeng
    Spring Clound 的Feigin更多是路由功能,将注解拼接成地址,Spring Cloud主要是整体完备,负载均衡、熔断啥的。
    2019-10-15
  • lizhibo
    老师 我想问的 Dubbo怎么更换成Protobuf 系列化协议?是要扩展Dubbo Serialization 接口吗?另外 Kryo 和 Protobuf 哪个性能高点啊

    作者回复: 是的,目前2.7版本已经加入了Protobuf序列化。Kryo和Protobuf 性能非常接近,Kryo序列化后的空间要比Protobuf小一些,但Protobuf序列化与反序列化的时间要优于Kryo。

    2019-09-28
  • 疯狂咸鱼
    老师,您说http是短链接,http1·1的keep alive 不是长链接么。或者用http2·0也算是优化吧?

    作者回复: 可手动设置keep alive,保持连接

    2019-09-14
  • godtrue
    课后思考及问题
    1:网上常见有关TCP和HTTP的问题,比如:
    TCP连接的建立详细过程?TCP的连接断开过程?
    三次握手建立连接,四次握手断开连接,感觉有些简单啦!如果面试时问到这个问题,老师建议该怎么回答?
    另外,还有问一次HTTP请求经过了几次TCP连接,这个如果面试时遇到了,老师又建议该怎么好好的回答?

    作者回复: 熟悉连接时为什么是三次握手,断开时为什么需要四次握手,以及粘包拆包的问题、解决方案。我理解的一次HTTP请求只有一次TCP连接。

    2019-09-07
  • 晓杰
    今天面试,我说springcloud的feign是rpc框架,然后他说不是,是伪rpc框架,请问老师springcloud的feign是rpc框架吗

    作者回复: feign是通过http实现接口请求,与传统的RPC框架有一定的区别,但也是一种RPC实现。

    2019-08-07
  • 晓晨同学
    有个问题请教一下老师
    1.一直不清楚通信协议和序列化协议的区别是什么,两者都是制定报文协议然后传输,感觉序列化协议更具体到业务属性

    作者回复: 通信协议是指我们传输信息的协议,包括头协议和包体,头协议中可能包含传输的id、包体大小、序列化方式等等信息,序列化则表示我们传输的包体的载体是什么样的格式,例如是将对象转成json格式还是转成xml格式,再转成二进制进行传输。

    2019-08-07
  • Joker
    老师厉害,层层递进啊。。。虽然可能我们目前没有用到,但是却是个非常好的地图啊。
    2019-07-09
  • 张德
    还知道JAVA和Python系统之间互相调用的thrift

    作者回复: thrift框架也很优秀

    2019-07-07
  • nightmare
    能不能讲一下netty的串行无锁化

    作者回复: Netty中,分为Reactor主线程和Reactor从线程,主线程主要用来监听连接事件,从线程主要用来处理监听I/O事件,以及处理读写I/O操作。

    一般有其他的业务操作,我们可以在handler中创建线程池来处理。但为了减少上下文切换,我们可以在ChannelPipeline上注册handler事件,例如解码过程。一般Reactor从线程监听到读操作,会立即调用ChannelPipeline的fireChannelRead方法完成读操作,在调用完读操作之后,会检查是否有其他handler,如果有,则直接调用,不会创建新的线程。

    这种方式的好处是,不用创建新的线程,在从线程中串行化完成所有的I/O以及业务操作,减少上下文切换;坏处是,给从线程带来了一定的阻塞。

    2019-06-13
  • 电光火石
    1. 老师线上有用过grpc吗,看文档说好像现在还不是特别的稳定?
    2. 文中的性能测试,http是否有打开keep alive?走tcp无疑更快,我只想知道用http会慢多少,因为毕竟http更简单。有看过其他的benchmark,在打开keep alive的情况下,性能也还行,不知道老师这个测试是否打开?另外,从测试结果上看,当单次请求数据量很大的时候,http比tcp好像查不了多少是吗?
    谢谢!

    作者回复: grpc目前很多公司在用,在Github中有源码阅读https://github.com/grpc。

    对的,没有打开keep alive,如果开启效果会好一些,减少了网络连接。

    2019-06-11
  • -W.LI-
    老师好!文中提到了高效的 Reactor 线程模型。有适合新手的资料链接么?还有个pr啥的能一起给我个么谢谢了,文中讲的看不懂。

    作者回复: 下一讲中会讲到Reactor、Proactor线程模型。

    2019-06-11
  • JackJin
    RPC要怎么学,项目中也用到了dubbo,可跟老师说的完全不一样,不是添加其他服务接口的依赖调用方法,而是发送http请求调用其他服务的接口。使我们用错了吗?
    有个疑问依赖其他的服务的接口调用方法,接口都没有实现怎么调用?

    作者回复: 请问你们用的什么协议?dubbo是消费服务类型,服务会注册接口到注册中心,消费端通过拉取注册中心的注册服务接口,与服务端通信。所以一般都是通过接口服务实现消息通信。

    2019-06-11
收起评论
25
返回
顶部