RPC粘包拆包

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1. 概念

  • RPC(Remote Procedure Call)泛指客户端与服务器端之间,通过网络进行数据交互的过程时,不需要了解网络底层实现的技术。我们接触的http、WebService、dubbo-rpc、rmi都可以称为是RPC的一种实现技术。
  • RPC的通性:
    • 寻址:客户端是如何知晓服务端具体(ip+端口)地址的;
    • 通讯方式:基于TCP/UDP或是更上层的协议,进行数据通信;
    • 数据序列化:请求响应的过程中,数据使用的序列化方式(xml,json,dubbo);
  • RPC框架:对上述RPC核心步骤进行了封装,不需要开发人员自己去定义协议、实现序列化等细节工作,这样的组件称为RPC框架。出于稳定性和数据可靠性的考虑,RPC框架通常选用TCP长连接作为传输协议。
  • TCP连接的三次握手:首先客户端会向服务器发送一次请求,以确认其能否收到请求,服务器收到请求之后会给客户端一次响应,此时客户端就知道其能够与服务器正常建立连接了,客户端就会向服务器再次发送请求建立连接,这就是TCP的三次握手的机制。
  • TCP连接的四次挥手:客户端在发送完数据之后会发送一次请求给服务端,告知其客户端将会结束数据请求,服务器接收到请求之后会返回一个同意的响应,客户端收到后就不会再发送数据了,但是服务器可能还有数据未发送完,此时处于一种半关闭的状态,等待服务器将数据发送完毕之后,服务器就会发送请求给客户端,告知其服务器可以结束请求了,此时客户端收到请求之后将会发送一次请求给服务器,以告知服务器关闭连接。

2. Socket编程

  • Internet中应用最广泛的网络应用编程接口,实现与3中底层协议接口:

    • 数据报类型套接字SOCK_DGRAM(面向UDP接口)
    • 流式套接字SOCK_STREAM(面向TCP接口)
    • 原始套接字SOCK_RAW(面向网络层协议接口IP、ICMP等)
  • 主要socket API及其调用过程

创建套接字-->端点绑定-->发送数据-->接收数据-->释放套接字

3. 长连接

  • 短连接:请求/响应之后,关闭已经建立的TCP连接,下次请求再建立一次连接;
  • 长连接:请求/响应之后,不关闭TCP连接,多次请求,复用同一个连接;
  • 为了避免频繁创建连接/释放连接带来的性能损耗,自定义的RPC框架,通常采用长连接的形式。

4. 粘包拆包

  • 粘包:多次请求,通过同一连接进行发送。服务端收到的数据包含了多次请求;
  • 拆包:一次发送的数据大于TCP发送缓冲区(16KB),分成多次进行传输、或者客户端发送的数据不完整。服务端单次收到的数据可能不完整。
  • 拆包的主要原因是RPC调用的时候,客户端向服务器发送多次请求时是使用的同一个连接,因而这些请求的数据是绑定在一起的,而由于TCP发送数据是有一个缓冲区的,这个缓冲区的大小为16KB,因而这些请求的数据发送到服务端之后,服务端每次接收的都可能是不完整的,因而服务端需要对发送过来的数据进行合并,一般客户端在发送数据时会定义一个分隔符,服务端在将数据合并之后再通过这个分隔符将数据进行拆分即可得到每个客户端发送的数据。

5. 实现Netty服务端

  • Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序;在保证易于开发的同事还保证了其应用的性能,稳定性和伸缩性。

6. 定义解码(拆分)规则

  • 数据的编解码规则是RPC协议的一部分,不同的协议,拆分方式不同。比如:Dubbo、gRpc、Motan-RPC、SOFA-RPC各有不同;

转载于:https://my.oschina.net/zhangxufeng/blog/2994991

你可能感兴趣的:(RPC粘包拆包)