入门RPC框架设计 | 青训营笔记

95 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第9天。本篇为第五届字节跳动青训营-寒假专场-后端基础课程的笔记。

RPC 入门

RPC-remote procedure calls-远程函数调用。

与之相对的是==本地函数调用==(这个过程就很常见了,都在本地执行)

相较于本地调用RPC具有以下特点: 1. 首先函数需要映射 2. 数据转为字节流(本地调用只需参数压栈) 3. 网络传输(需要某种协议,两个进程)

一个完整的RPC过程

  1. 通过完整的IDL-Interface Description Language 文件,进行代码生成(通过编译工具将上述文件转为静态库)
  2. 基于通信协议对调用内容的编码解码
  3. 进行网络传输:一般基于成熟网络库走TCP/UDP

RPC 的优劣势

  1. 优点
    1. 可拓展
    2. 故障隔离
    3. 单一职责:方便协作开发和运维
  2. 坏处
    1. 调用异常
      1. 服务宕机
      2. 网络传输不畅

RPC框架的架构

==思想:分层设计==

优点:

  1. 结构清晰
  2. 松耦合
  3. 适合协作开发,易于调试

分层式结构同样也具有一些缺陷:

  1. 降低了系统的性能。
  2. 有时会导致级联的修改。

分层示意图:

Pasted image 20230210151703.png

IDL 文件转换

graph TD

Client --> IDLFile
Server --> IDLFile
IDLFile --generate--> Golang
IDLFile --generate--> C++
IDLFile --generate--> Java

编解码

常见的编解码解决方案有:

  1. 基于特定编码格式的:比如:java.io.Serializable
  2. 文本:JSON, XML, CSV
  3. 二进制编码(protobuf等等)
    1. 跨平台
    2. 高性能

如何在实际项目中选型?

  1. 根据兼容性
  2. 通用性
  3. 性能(数据传输量,处理耗时)

RPC框架的架构关键属性

  1. 稳定性保障: 1. 熔断(保护调用方) 2. 限流(保护被调用方) 3. 超时控制(比如重试) 4. 提高请求成功率 1. 负载均衡 2. 重试 5. 长尾请求(部分响应时间超过平均同类请求time的请求)的优化 1. backup Request 6. 注册中间件
  2. 易用性: 1. 开箱即用:合理提供默认参数,以及丰富的文档 2. 丰富高效的周边工具 1. 代码生成 2. 脚手架工具 3. ...
  3. 可拓展性
  4. 可观测性(方便测试,运维) 1. Log 2. Metric 3. Tracing 4. 内置观测性服务
  5. 性能 1. 高吞吐 2. 低延迟 3. 当然上述不是都能达到极致,需要根据场景判断

RPC框架设计实战

  1. 网络库优化
    1. 读写并行无锁,nocopy读写
    2. 对象池化,减少GC开销
  2. 编解码优化
    1. Codegen
      1. 预计算分配内存
    2. JIT
      1. 动态编译技术
  3. 合并部署:解决微服务过微,传输序列化开销越来越大的问题
    1. 将亲和性强的服务实例尽可能调度到同一个物理机:远程RPC优化为IPC调用,这样大大提高稳定性和响应时间,充分利用系统资源