Willson Chen

Stay Hungry, Stay Foolish.

RPC 基础

RPC

RPC(Remote Procedure Call),远程过程调用,用于将网络通信简化为本地函数调用。
RPC 可以使分布式应用内部通信更加简单高效。
RPC 是一种方法论,RPC 协议是一组规范或标准,而 RPC 框架则提供了基于协议的实现。

RPC 协议构成

  • 接口标准,如通过特定IDL 来定义接口。
  • 传输协议标准,如通过TCP、HTTP进行网络传输。
  • 序列化协议,如通过JSON、ProtoBuf等进行序列化。

RPC 框架构成

  • 客户端接口存根,代理客户端调用。
  • 网络传输模块,利用传输协议处理客户端和服务端的数据传输。
  • 序列化模块,将请求和返回值转换为网络传输的数据。
  • 服务端接口存根,监听网络请求处理服务端调用发送处理结果。
  • 框架以客户端和服务端的依赖库、代码生成工具集等形式提供。

一次 RPC 调用的流程

  • 客户端以本地函数调用方式调用服务。
  • 客户端存根收到请求将方法、入参等信息序列化成能够网络传输的消息体。
  • 客户端存根找到远程的服务地址,将消息通过网络发送给服务端。
  • 服务端存根收到消息进行反序列化,然后调用本地服务进行处理。
  • 服务端本地服务处理后返回结果给服务端存根。
  • 服务端存根序列化结果并发送给客户端。
  • 客户端存根收到消息进行反序列化。
  • 客户端获得最终结果。

服务端IO模型

  • 同步阻塞IO:线程阻塞,直到有数据才恢复。
  • 同步非阻塞IO:线程不阻塞,需要轮询判断是否有数据。
  • 同步多路复用IO:一个线程监听多个 IO,哪个有数据了就交给对应线程处理。
  • 异步IO:内核直接将数据复制到用户空间。

服务端线程模型

  • 单线程模型
    • 一个线程处理所有请求
    • 同个时间只能处理一个请求
    • 仅开发调试用
  • 多线程短连接模型
    • 一个线程处理一个请求,完成后关闭连接
    • 有多少并发请求就有多少线程,线程数有限
    • 频繁建立网络连接开销大
  • 多线程长连接模型
    • 一个线程处理一个连接上的多个请求,服务端不关闭连接。
    • 请求频率低时浪费资源,并发量大时无法处理。
  • 线程池模型
    • 提前创建好一定数量的线程,请求来了分配给空闲线程处理。
    • 本质上是生产者-消费者模型
    • 同样可以支持短连接或长连接。

服务端 reactor 模式

  • 在多路复用IO模型的epoll方式基础上的模式。
  • reactor 为反应堆,表示一个多路复用器。
  • 单 reactor 单线程模式:
    • 只有一个主线程运行 reactor(一个epoll) 和处理事件。
  • 单 reactor 多线程(协程)模式:
    • 一个主线程运行 reactor(一个epoll),通过工作线程(或协程)处理事件。
  • 主从 reactor 多线程模式:
    • 一个主reactor负责建立连接,多个从reactor负责处理 IO 操作。

常用 RPC 框架

  • gRPC
    • Google 开发的开源 RPC 框架,属于云原生 CNCF 的一部分。
    • 通过 protobuf 定义接口,支持为各种开发语言自动生成客户端和服务端存根。
    • 高性能,支持二进制序列化协议。
    • 通信协议基于 HTTP2,支持双向流,消息头压缩,多路复用,服务端推送等。
    • 支持请求响应式和流式 RPC。