RPC原理与实现 | 青训营笔记

77 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天

RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务

基本概念

本地函数调用

1、将a和b的值压栈

2、通过函数指针找到calculate函数,进入函数取出栈中的值2和3,将其赋予x和y

3、计算x*y,并将结果存在z

4、将z的值压栈,然后从calculate返回

5、从栈中取出z返回值,并赋值给result

func main() {
    var a=2
    var b=3
    result := calculate(a,b)
    fmt.Println(result)
    return
}

func calculate(x,y int) {
    z := x*y
    return z
}

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

RPC需要解决的问题

  1. 函数映射
  2. 数据转换成字节流
  3. 网络传输

网上商城-----------支付100元----------->支付服务--------余额减掉100元--------->返回扣款成功--------->网上商城

RPC概念模型

1984年Neison发表了论文《Implementing Remote Procedure Calls》,其中提出了RPC的过程由5个模型组成:Users、User-Stub、RPC-Runtime、Server-Stub、Server

image.png

一次完整的RPC过程

IDL(Interface description language)文件

IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和不同语言编写的程序可以相互通信。

生成代码

通过编译器工具把IDL文件转换成语言对应的静态库

编解码

从内存中表示到字节序列的转换成为编码,反之为解码,也常常叫做序列化和反序列化

通信协议

规范了数据在网络中的传输内容和格式,除必须的请求/响应数据外,通常还会包含额外的元数据

RPC的优点

  1. 单一职责,有利于分工协作和运维开发
  2. 可扩展性强,资源使用率更优
  3. 故障隔离,服务的整体可靠性更高

image.png

RPC的缺点

  1. 服务宕机,对方应该如何处理
  2. 在调用过程中发生网络异常,如何保证消息的可达性
  3. 请求量突然增加导致服务无法及时处理,有哪些应对措施

分层设计

分层设计 - 以Apache Thrift为例

image.png

编解码层 - 生成代码

image.png

编解码层 - 数据格式

  • 语言特定的格式
  • 文本格式
  • 二进制编码

编解码层 - 二进制编码

TLV编码

  • Tag:标签,可以理解为类型
  • Length:长度
  • Value:值,这个值也可以十个TLV结构

编解码层 - 选型

  • 兼容性 支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
  • 通用性 支持跨平台,跨语言
  • 性能 从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长。

协议层 - 概念

  • 特殊结束符 一个特殊字符作为每个协议单元结束的标示
  • 变长协议 以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度

协议层 - 协议构造

image.png

协议层 - 协议解析

image.png

网络通信层 - Sockets API

image.png

网络通信层 - 网络库

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

关键指标

稳定性 - 保障策略

  • 熔断
  • 限流
  • 超时控制

image.png

稳定性 - 请求成功率

负载均衡、重试

稳定性 - 长尾请求

稳定性 - 注册中间件

易用性

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

扩展性

  • Middleware
  • Option
  • 编解码层
  • 协议层
  • 网络传输层
  • 代码生成工具插件扩展

观测性

  • Log、Metric、Tracing
  • 内置观测性服务

高性能

image.png

企业实践

整体架构 - Kitex

  • Kitex Core 核心组件
  • Kitex Byted 与公司内部基础设施集成
  • Kitex Tool 代码生成工具

自研网络库

背景

  • 原生库无法感知连接状态
  • 原生库存在goroutine暴涨的风险

Netpoll

  • 解决无法感知连接状态问题
  • 解决goroutine暴涨的风险
  • 提升性能

扩展性设计

image.png

性能优化

网络库优化

  • 调度优化
  • LinkeBuffer
  • Pool

编解码优化

  • Codegen
  • JIT

合并部署

微服务过微,传输和序列化开销越来越大。将亲和性强的服务实例尽可能调度到同一个物理机,远程RPC调用优化为本地RPC调用。

image.png