深入浅出RPC框架 | 豆包MarsCode AI 刷题

117 阅读3分钟

RPC 基本概念

远程调用函数( RPC - Remote Procedure Calls )

所谓的远程调用函数,就是本地服务通过网络,向远程的某个服务发送请求,调用某个函数。这存在以下有待解决的问题:

  • 函数映射

  • 数据转换成字节流

  • 网络传输

RPC 概念模型如下所示,首先调用机器进行本地调用,将参数打包,通过网络传输给被调用机器。然后,被调用机器解包参数,调用函数得到计算结果,将结果打包,通过网络传输给调用机器。然后,调用机器解包结果,返回本地调用结果。

2024-11-14-17-43-17-image.png

RPC 的好处

  • 单一职责,有利于分工协作和运维开发

  • 可扩展性强,资源使用率更优

  • 故障隔离,服务的整体可靠性更高。

RPC 带来的问题

  • 服务宕机,对方应该如何处理?

  • 在调用过程中发生网络异常,如何保证消息的可达性?

  • 请求数量突增导致服务无法及时处理,有哪些应对措施?

分层设计

RPC 分层设计大致如下所示,主要分为业务逻辑代码, IDL 文件生成的代码,编解码层,协议层,网络通信层。

2024-11-14-20-01-39-image.png

生成代码

客户端、服务端同时依赖同一份 IDL ( Interface Definition Language ) 文件,该 IDL 文件可以转换生成为不同编程语言如: Golang, C++, Java.

2024-11-14-20-03-53-image.png

编解码层

  • 语言特定格式:许多编程语言都内建了将内存对象编码为字节序列的支持,例如 Java 有 java.io.Serializable

  • 文本格式: JSON, XML, CSV 等文本格式,具有人类可读性

  • 二进制编码:具备跨语言和高性能的优点。

例如 TLV 编码 - 二进制编码, Tag 表示标签,可以理解为类型 Length 表示成都 Value 值。

例如对于 Person 结构,userName 取值 Martin , favoriteNumber 取值 1337, interests 取值 { daydreaming, hacking }.

struct Person {
    1: string        userName,
    2: i64           favoriteNumber,
    3: list<string>  interests
}

2024-11-14-20-14-09-image.png

协议层

协议层内容的表示方式分为两类:1. 特殊结束符:一个特殊字符作为每个协议单元结束的标识。2. 变长协议:以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度。

协议的解析通常分为以下三步骤,获取 MagicNumber, 获取编码后的载体,进行解码,获取原来的载体:

2024-11-14-20-17-57-image.png

关键指标

稳定性

保障策略

  • 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路。

  • 限流:保护被调用方,防止大流量把服务压垮。

  • 超时控制:避免浪费资源在不可用节点上。

请求成功率

负载均衡、请求重试策略。

长尾请求

长尾请求指的是那些请求耗时大于所有请求耗时中99%的请求,它们的请求耗时很长,但只占一小部分。解决方案:先预设定一个阈值 t3 , 当 Req1 发送出去后 t3 时间都没有返回,则重新发送 Req2, 相当于同时有两个请求运行。然后等待请求返回,只要 Resp1 或者 Resp2 任意一个返回成功的结果,就可以立即结束这次请求。相比于等待超时后再发送请求,能大大减少整体延时。

易用性

  • 开箱即用:合理的默认参数选项、丰富的文档

  • 周边工具:生成代码工具、脚手架工具

观测性

  • 日志、性能指标、链路追踪

  • 内置观测性服务,例如:环境变量、配置、服务初始化参数、缓存信息。

高性能

目标

  • 高吞吐

  • 低延迟

手段

  • 连接池

  • 多路复用

  • 高性能编解码协议

  • 高性能网络库