RPC | 青训营

76 阅读4分钟

Remote Procedure Call

远程函数调用指在本地通过网络调用一个服务端的函数。

RPC需要解决的问题:

  • 函数映射:与本地函数不同,我们无法获取远程函数的内存地址,一个远程函数必须被映射到本地才能被调用,例如通过字符ID表示一个远程函数
  • 将数据转换成字节流:远程函数的输入/输出必须被编码为字节流并通过网络传输,而不是简单的压入/弹出栈内存。
  • 网络传输:远程函数的调用通过网络完成。

1984年Nelson提出的RPC概念模型:

  1. 用户代码调用远程函数
  2. 函数参数通过User-stub打包
  3. 数据通过网络被发送到远程机器
  4. 远程机器通过Server-stub解包参数
  5. 远程机器调用指定的函数
  6. 远程机器通过Server-stub打包返回数据
  7. 用户机器收到结果后,通过User-stub解包
  8. 调用函数得到返回值

为了实现RPC,我们需要定义远程函数的调用方式,输入/输出编解码,以及通信协议:

  • IDL (Interface Description Language) 文件:通过一种语言中立的、跨平台的方式来描述接口,是不同平台上运行不同语言编写的程序可以互相通信
  • 代码生成工具:用于把IDL文件描述的函数转换成对应一个特定语言的静态库
  • 编解码:数据在内存中的二进制表示到字节序列的相互转换
  • 通信协议:规定数据在网络中的传输内容与格式,通常包含额外的元数据
    • 通常使用TCP/UDP传输

RPC的好处

  • 函数/服务的单一职责,有利于分工协作和运维开发
  • 可扩展性强
  • 故障隔离,提高整体服务可靠性

RPC的问题

  • 远程服务宕机时,调用方应该如何处理?
  • RPC调用过程中发生网络异常,如何保证消息可达?
  • 请求量突增导致服务无法及时处理,应该如何应对?

RPC框架需要解决以上这些问题。

RPC框架设计

RPC框架通过分层设计完成RPC调用概念模型的每个步骤:

数据格式

函数的输入/输出数据在不同情况下有不同的表现形式:

  • 语言特定的二进制格式:编程语言内建的将对象编码为字节序列的支持,例如Java的java.io.Serializable
  • 文本格式:JSON、XML、CSV(对人类可读性高)
  • 二进制格式:跨语言、高性能的二进制格式,例如:Thrift的BinaryProtocol,Protobuf

Thrift BinaryProtocal使用TLV编码:

  • Tag: 标签,表示类型和结构中的指定成员
  • Length: 对象字节序列长度
  • Value: 对象的值,可以是任何二进制序列,值也可以是一个TLV结构(允许嵌套)

选择合适的编码方案需要考虑:

  • 兼容性:支持增加新的字段时向前兼容
  • 通用性:跨平台、跨语言
  • 性能:编码解码开销、编码后的数据大小

协议层

定义协议单元

  • 通过特殊字符作为结束标识

  • 在开头添加一个定长整数表示长度,用于实现变长协议

Thrift协议:

协议解析

网络通信层

  • 提供易用API
    • 封装底层 Socket API
    • 连接管理和事件分发
  • 功能
    • 协议支持:TCP,UDP,UDS等
    • 优雅退出、异常处理
  • 性能
    • 应用层buffer减少copy
    • 高性能定时器、对象池等

RPC框架关键指标

稳定性

保障策略:

  • 熔断:一个服务调用另一个服务时,如果被调用的服务出现问题导致请求超时,那么调用方应该停止使用这个出现问题的服务,防止大量请求积压在调用方导致更多服务崩溃。
  • 限流:保护被调用的服务,防止大流量把服务压垮
  • 超时控制:避免浪费资源在不可用节点上

提高请求成功率:

  • 负载均衡:尽可能将请求分配给负载低的实例
  • 重试:请求服务超时时可以尝试重试

备份请求与长尾请求:

  • 有时候一个请求可能由于某些原因比正常情况需要更长的响应时间,这样的请求被称为长尾请求
  • 可以根据经验计算一个请求预期的响应时间指标,例如p99(99%的请求响应时间小于该值)
  • 在超过阈值且没有收到响应时,立即发送备份请求Req2进行重试,如果备份请求正常返回,那么不必等待长尾请求的结果。

RPC框架通常允许通过注册中间件的方式配置这些策略。

易用性

  • 开箱即用,包含合理的默认参数选项、丰富的文档
  • 周边工具:生成代码工具、脚手架工具

扩展性

允许对RPC调用过程的各个层级进行扩展

观测性

内置Log, Metric, Tracing(链路跟踪)等服务