浅谈rpc技术

1. rpc是什么?

rpc是远程过程调用(remote procedure call)的缩写,大意是调用远程的函数并得到返回结果。比如远程服务集成了【人脸识别算法】,客户端通过与服务端的rpc调用即可获取人脸识别的能力,这种方式可以降低系统耦合度、简化开发成本等等。

rpc的网络交互大致流程:

  1. client向server发送request后开始等待。
  2. server收到、处理、回复client。
  3. client收到response做出反应。

简单代码demo如下:

1
2
3
4
5
6
7
8
9
// 1. client侧
write(netfd, req_buf, req_size);
... // wait response
read(netfd, res_buf, res_size);

// 2. server侧
read(netfd, req_buf, req_size);
... // 执行函数逻辑、业务逻辑等
write(netfd, res_buf, res_size);

上述demo是操作系统级别比较原生的写法,对开发人员不太优化,比如无法对协议字段约束、没有较好的容错处理、缺乏便捷的序列化/反序列化方式、难以映射Call ID等问题。

为了进一步降低rpc服务的开发门槛、提高rpc代码的质量等,大佬们对rpc的生命周期进行抽象、建模以及标准化,设计了各种各样的rpc框架。

2. rpc框架介绍

rpc框架提供了一整套的技术栈,用来规范和解决rpc过程调用可能遇到的问题,比如:

  • 数据传输协议:不同机器、网络间可能是不同的字节序;如何快速序列化和反序列化?随着业务变化,数据字段往往要增加或删减,怎么兼容前后不同版本的格式?
  • 连接建立和管理:如何建立client/server的链接?如何从集群选择一台机器发出请求?如何建立短连接、长连接、连接池等。
  • 请求处理和响应:如何解析请求?如何处理业务逻辑?如何组装返回结果等。
  • 各种容错处理:下游迟迟不返回怎么办?找不到可用下游怎么处理?链接断开的异常处理等等
  • 监控和工具集(可选):内置metrics指标监控,提供工具集用于性能分析&问题追查等。
  • 等等

简化的rpc架构demo图:https://www.guru99.com/remote-procedure-call-rpc.html

主要包含:

  1. Client:发出请求包 & 接收响应包,包括一些容错处理等等。
  2. Client Stub:用于序列化/反序列化消息包,并与rpc runtime做消息的交互。
  3. RPC Runtime:rpc框架核心运行环境,比如连接管理、容错处理等等
  4. Server Stub:和Client Stub功能类似
  5. Server:收到请求包并处理业务逻辑(比如执行人脸识别程序),组成返回结果等。

工业级的rpc框架功能更加强大、架构设计也更加复杂,比如会支持:

  • 多协议:protobuf协议、json协议、redis协议、mysql协议等等
  • 多语言:C/C++/Golang/Java/PHP等等
  • 多平台:Linux/Mac/Windows等
  • 多服务发现策略:比如ipport、dns、etcd、k8s svc等等
  • 多负载均衡策略:round robin、random、weighted random(指定权重)、locality aware(延迟判断权重)
  • 等等

3. 各大rpc框架的介绍

3.1 grpc简介(google rpc)

grpc是google公司开源的高性能、多语言、跨平台的通用rpc框架,它依赖 HTTP/2、protobuf和其他现代技术堆来保证rpc的安全、高性能和可扩展性,大致流程如下:

核心概念包括:

  • protobuf:一种序列化/反序列化协议,可以低成本定义service接口以及结构体,并自动产出语言相关的lib库。详细参考:https://zhuanlan.zhihu.com/p/435944782
  • streaming:一次请求会包含多次处理过程,主要借助HTTP/2的能力实现,主要解决通信包体太大,难以一次传输完成处理的场景。
    • server streaming rpc:client发送单个请求 & 接受一系列的数据包,消息是保序的,且一直持续到server无消息发送。
    • client streaming rpc:client发送一系列的数据包 & 得到一个响应包,grpc保证包的发送顺序和接收顺序。
    • bidirectional streaming rpc:双向streaming,两路streaming操作是独立的。
  • HTTP/2:grpc基于HTTP/2开发,同时兼容了HTTP/1.1,https://developers.google.com/web/fundamentals/performance/http2?hl=zh-cn 优点如下:
    • 二进制分帧层:提高消息传输的效率。
    • 支持流式传输
    • 支持流量控制
    • header压缩
    • 等等
  • channels: HTTP/2支持一个链接上进行多个stream,channel通过多个stream实现了并发链接,提供了一种根据ip:port连接到 grpc server的方法。

相比REST+JSON

grpc优势:

  • 高性能:快10倍以上
  • 多种传输方式:普通请求、单向stream、双向stream
  • 代码自动生成:通过工具自动生成协议代码:包括数据结构定义、服务接口定义
  • 跨平台/多语言支持:Linux/Windows/Mac,C++/Golang/PHP等
  • 安全:支持TLS
  • 其他特性:加密、metdata、认证、拦截机制、服务发现、负载均衡等等

grpc劣势:

  • 对浏览器支持不太优化:grpc严重依赖HTTP/2,浏览器需要web同时支持HTTP/1.1和HTTP/2。
  • 分析和调试较为麻烦:protobuf是二进制难以编辑、阅读。
  • 上手门槛较高

3.2 brpc简介(baidu rpc)

brpc是百度开源的工业级rpc框架,被广泛应用在百度上百万实例、数千种服务端程序中。 为什么叫工业级rpc框架?因为它设计之初就考虑了生产环境遇到的各类问题,

  • 数据交换协议五花八门:http+json、protobuf、nshead+mcpack、自定义协议,那么服务端如何支持多种协议的访问?
  • 服务发现协议多种多样:ipport、dns、bns、xns、etcd等,如何支持多种协议的访问?
  • 密集IO场景下如何压榨CPU的极限?
  • 复杂调度场景下,如何选择合适的后端?
  • 全面的调试和监控手段:内置各种Metrcis、支持在线分析性能、race condition分析等等。
  • 等等

此外brpc通过将策略和架构解耦的方式,实现了强大的定制能力,比如定制服务发现协议、定制数据交换协议等等,以支持更多更个性化的rpc场景。

brpc框架组成大致为:

brpc vs grpc 的优势:

  • 功能方面:除了基础的rpc功能之外,brpc还扩展支持了多种数据交换协议、多种调度策略、多种服务发现方式等等。
  • 性能方面:brpc借助bthread、lock-free等技术,在某些场景下性能表现优异。
  • 定制方面:通过架构、策略解耦的方式,支持定制扩展rpc的功能。
  • 运维层面:内置了各种便捷服务(比如监控页面、性能分析、参数控制等)

劣势:

  • 跨平台/跨语言能力不足
  • 上手门槛相对较高

4. 参考