深入浅出RPC框架 | 青训营笔记

102 阅读5分钟

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

深入浅出RPC框架

基本概念

RPC(远程过程调用)

一次RPC的完整过程

  1. IDL:(Interface description language)接口描述语言文件。通过IDL一种中立的方式描述接口,使得在不同平台语言上编写的程序可以相互通信

  2. 生成代码

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

  3. 编解码

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

  4. 通信协议

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

  5. 网络传输

    通常基于成熟的网络库走TCP/UDP传输

RPC的好处

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

RPC带来的问题

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

分层设计

主要可以分为三层:

  1. 编解码层:通过代码生成工具把IDL文件转化成不同语言对应的lib代码,里面封装了请求数据的编解码逻辑
  2. 协议层:框架的RPC协议层,规定了传输内容和格式
  3. 网络通信层:框架的网络通信层,通常是走TCP或http2

编解码层

编码:将特定语言对象编码成二进制的IDL数据格式

解码:将二进制的IDL数据格式解码成特定语言对象

数据格式

编解码层的数据格式要具备以下能力:

  1. 多种语言支持编解码。编码能够适配多种语言,请求或响应信息能够转化为各种语言的对象,不能与特定的语言绑死,
  2. 具有可读性。
  3. 类型区分度强。能够区分字段具体类型如浮点型(JSON格式不可以区分浮点型,并且JSON格式会精度丢失)

image-20230210154243929

所以在编解码层使用二进制编码:

具备跨语言和高性能等优点,常见有Thrift的BinaryProtocal,Protobuf等

编解码层的二进制编码:

image-20230210160017121

一个BinaryProtocal编码二进制格式

选型

二进制编解码选型需要满足的条件:

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

Thrift和Protobuf在二进制编解码层面做的都是非常优秀的

协议层

协议构造

image-20230210160753552

  • LENGTH:数据包大小,不包含自身
  • HEADER MAGIC:标识版本信息,协议解析时候快速校验
  • SEQUENCE NUMBER:表示数据包的segID,可用于多路复用,单连接内递增
  • HEADER SIZE:头部长度,从第14个字节开始计算一直到PAYLOAD前
  • PROTOCOL ID:编解码方式,有Binary和Compact两种
  • TRANSFORM ID:压缩方式,如Zib和snappy
  • INFO ID:传递一些定制的meta信息PAYLOAD:消息体

协议解析

协议解析的过程就是一步一步读取字节内容转化成最终有用的信息

image-20230210161226810

网络传输层

image-20230210161305829

通常就是利用系统层面的Sockets API来进行管理和控制TCP传输,可以用语言本身的net库也可以用第三方网络库进行编程

网络库

  1. 提供简单易用的API

    • 封装操作系统的Socket API
    • 连接管理和事件分发
  2. 功能:

    • 协议支持:TCP、UDP、和uds等
    • 优雅退出,异常处理
  3. 性能:

    • 应用层buffer减少copy
    • 高性能定时器、对象池等

结论

  1. RPC框架的主要核心有三层,编解码层、通信协议层、网络传输层
  2. 二进制编码的数据格式和选型要点
  3. 协议的构造、框架解析协议的流程,实现网络通信
  4. 选取网络库进行Socket API编程实现网络传输

关键指标

稳定性

  1. 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
  2. 限流:保护被调用方,防止大流量把服务压垮
  3. 超时控制:避免浪费资源在不可用节点上
  4. 负载均衡+重试

易用性

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

扩展性

  1. Middleware
  2. Option
  3. 编解码层
  4. 协议层
  5. 网络传输层
  6. 代码生成工具插件扩展

观测性

  1. Log、Metric、Tracing
  2. 内置观测性服务

高性能

  1. 高吞吐
  2. 低延迟
  3. 手段:连接池、多路复用、高性能编解码协议、高性能网络库

Kitex RPC框架

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

image-20230210162937267

网络库Netpoll

go原生网络库的弊端:

  1. 原生库无法感知连接状态:在使用连接池时,池中存在失效连接,影响连接池的复用。
  2. 原生库存在goroutine暴涨的风险:一个连接一个goroutine的模式,由于连接利用率低下,存在大量goroutine占用调度开销,影响性能。

Netpoll优势:

  1. 解决无法感知连接状态问题:引入epoll主动监听机制,感知连接状态
  2. 解决goroutine暴涨的风险:建立goroutine池,复用goroutine
  3. 提升性能:引入Nocopy Buffer,.向上层提供NoCopy的调用接口,编解码层面零拷贝

特性

支持多协议,支持灵活的自定义协议的扩展

image-20230210163417435

总结

  1. RPC框架主要三层:编解码层、通信协议层、网络传输层
  2. RPC框架性能指标:稳定性、可扩展性、高性能等
  3. Kitex RPC框架简介和Netpoll优势