Java性能之优化RPC网络通信

服务框架的核心

  1. 大型服务框架的核心:RPC通信
  2. 微服务的核心是远程通信和服务治理
  • 远程通信提供了服务之间通信的桥梁,服务治理提供了服务的后勤保障
  1. 服务的拆分增加了通信的成本,因此远程通信很容易成为系统瓶颈
  • 在满足一定的服务治理需求的前提下,对远程通信的性能需求是技术选型的主要影响因素
  1. 很多微服务框架中的服务通信是基于RPC通信实现的
  • 在没有进行组件扩展的前提下,Spring Cloud是基于Feign组件实现RPC通信(基于HTTP+JSON序列化)
  • Dubbo是基于SPI扩展了很多RPC通信框架,包括RMI、Dubbo、Hessian等(默认为Dubbo+Hessian序列化)
 
性能测试基于Dubbo:2.6.4,单一TCP长连接+Protobuf(响应时间和吞吐量更优),短连接的HTTP+JSON序列化
Java性能之优化RPC网络通信

文章插图
 

Java性能之优化RPC网络通信

文章插图
 
RPC通信架构演化
无论是微服务、SOA、还是RPC架构,都是分布式服务架构,都需要实现服务之间的互相通信,通常把这种通信统称为RPC通信
Java性能之优化RPC网络通信

文章插图
 
概念
  1. RPC:Remote Process Call,远程服务调用,通过网络请求远程计算机程序服务的通信技术
  2. RPC框架封装了底层网络通信和序列化等技术
  • 只需要在项目中引入各个服务的接口包,就可以在代码中调用RPC服务(如同调用本地方法一样)
RMI
  1. RMI:Remote Method Invocation
  2. RMI是JDK自带的RPC通信框架,已经成熟地应用于EJB和Spring,是纯JAVA网络分布式应用系统的核心解决方案
  3. RMI实现了一台虚拟机应用对远程方法的调用可以同对本地方法调用一样,RMI封装好了远程通信的具体细节
实现原理
Java性能之优化RPC网络通信

文章插图
 
  1. RMI远程代理对象是RMI中最核心的组件,除了对象本身所在的虚拟机,其他虚拟机也可以调用此对象的方法
  2. 这些虚拟机可以分布在不同的主机上,通过远程代理对象,远程应用可以用网络协议和服务进行通信
高并发下的性能瓶颈
  1. Java默认序列化
  • RMI的序列化方式采用的是Java默认序列化,性能不好,而且不支持跨语言
  1. TCP短连接
  • RMI是基于TCP短连接实现的,在高并发情况下,大量请求会带来大量TCP连接的创建和销毁,非常消耗性能
  1. 阻塞式网络IO
  • Socket编程中使用传统的IO模型,在高并发场景下基于短连接实现的网络通信就很容易产生IO阻塞,性能将大打折扣
优化路径TCP / UDP
  1. 网络传输协议有TCP和UDP,两个协议都是基于Socket编程
  2. 基于TCP协议实现的Socket通信是有连接的
  • 传输数据要通过三次握手来实现数据传输的可靠性,而传输数据是没有边界的,采用的是字节流模式
  1. 基于UDP协议实现的Socket通信,客户端不需要建立连接,只需要创建一个套接字发送数据给服务端
  • 基于UDP协议实现的Socket通信具有不可靠性
  • UDP发送的数据采用的是数据报模式,每个UDP的数据报都有一个长度,该长度与数据一起发送到服务端
  1. 为了保证数据传输的可靠性,通常情况下会采用TCP协议
  • 在局域网且对数据传输的可靠性没有要求的情况下,可以考虑使用UDP协议,UDP协议的效率比TCP协议高

Java性能之优化RPC网络通信

文章插图
 
长连接
  1. 服务之间的通信不同于客户端与服务端之间的通信
  2. 由于客户端数量众多,基于短连接实现请求,可以避免长时间地占用连接,导致系统资源浪费
  3. 服务之间的通信,连接的消费端不会像客户端那么多,但消费端向服务端请求的数量却一样多
  • 基于长连接实现,可以省去大量建立TCP连接和关闭TCP连接的操作,从而减少系统的性能消耗,节省时间
 
优化Socket通信
  1. 传统的Socket通信主要存在IO阻塞,线程模型缺陷以及内存拷贝等问题,Netty4对Socket通信编程做了很多方面的优化
  2. 实现非阻塞IO:多路复用器Selector实现了非阻塞IO通信
  3. 高效的Reactor线程模型