这是我参与「第五届青训营」笔记创作活动的第十天
深入浅出RPC框架
基本概念
RPC(远程过程调用)
一次RPC的完整过程
-
IDL:(Interface description language)接口描述语言文件。通过IDL一种中立的方式描述接口,使得在不同平台语言上编写的程序可以相互通信
-
生成代码
通过编译器工具把IDL文件转化成语言对应的静态库
-
编解码
从内存中表示到字节序列的过程称为编码,反之为解码,也常叫做序列化和反序列化
-
通信协议
规范了数据在网络传输中的传输内容和格式。除了必须的请求/响应数据外,通常还会包括必要的元数据
-
网络传输
通常基于成熟的网络库走TCP/UDP传输
RPC的好处
- 单一职责,有利于分工协作和维护开发
- 可扩展性强,资源利用率更优
- 故障隔离,服务的整体可靠性更高
RPC带来的问题
- 服务宕机,对方应该如何处理?
- 在调用过程中发生网络异常,如何保证消息的可达性?
- 请求量突增导致服务无法及时处理,有哪些应对措施?
分层设计
主要可以分为三层:
- 编解码层:通过代码生成工具把IDL文件转化成不同语言对应的lib代码,里面封装了请求数据的编解码逻辑
- 协议层:框架的RPC协议层,规定了传输内容和格式
- 网络通信层:框架的网络通信层,通常是走TCP或http2
编解码层
编码:将特定语言对象编码成二进制的IDL数据格式
解码:将二进制的IDL数据格式解码成特定语言对象
数据格式
编解码层的数据格式要具备以下能力:
- 多种语言支持编解码。编码能够适配多种语言,请求或响应信息能够转化为各种语言的对象,不能与特定的语言绑死,
- 具有可读性。
- 类型区分度强。能够区分字段具体类型如浮点型(JSON格式不可以区分浮点型,并且JSON格式会精度丢失)
所以在编解码层使用二进制编码:
具备跨语言和高性能等优点,常见有Thrift的BinaryProtocal,Protobuf等
编解码层的二进制编码:
一个BinaryProtocal编码二进制格式
选型
二进制编解码选型需要满足的条件:
- 兼容性:自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
- 通用型:支持跨平台,跨语言
- 性能:从空间和时间两个维度考虑,也就是编码后数据大小和编码耗费时常
Thrift和Protobuf在二进制编解码层面做的都是非常优秀的
协议层
协议构造
- LENGTH:数据包大小,不包含自身
- HEADER MAGIC:标识版本信息,协议解析时候快速校验
- SEQUENCE NUMBER:表示数据包的segID,可用于多路复用,单连接内递增
- HEADER SIZE:头部长度,从第14个字节开始计算一直到PAYLOAD前
- PROTOCOL ID:编解码方式,有Binary和Compact两种
- TRANSFORM ID:压缩方式,如Zib和snappy
- INFO ID:传递一些定制的meta信息PAYLOAD:消息体
协议解析
协议解析的过程就是一步一步读取字节内容转化成最终有用的信息
网络传输层
通常就是利用系统层面的Sockets API来进行管理和控制TCP传输,可以用语言本身的net库也可以用第三方网络库进行编程
网络库
-
提供简单易用的API
- 封装操作系统的Socket API
- 连接管理和事件分发
-
功能:
- 协议支持:TCP、UDP、和uds等
- 优雅退出,异常处理
-
性能:
- 应用层buffer减少copy
- 高性能定时器、对象池等
结论
- RPC框架的主要核心有三层,编解码层、通信协议层、网络传输层
- 二进制编码的数据格式和选型要点
- 协议的构造、框架解析协议的流程,实现网络通信
- 选取网络库进行Socket API编程实现网络传输
关键指标
稳定性
- 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
- 限流:保护被调用方,防止大流量把服务压垮
- 超时控制:避免浪费资源在不可用节点上
- 负载均衡+重试
易用性
- 开箱即用:合理的默认参数选项、丰富的文档
- 周边工具:生成代码工具、脚手架工具
扩展性
- Middleware
- Option
- 编解码层
- 协议层
- 网络传输层
- 代码生成工具插件扩展
观测性
- Log、Metric、Tracing
- 内置观测性服务
高性能
- 高吞吐
- 低延迟
- 手段:连接池、多路复用、高性能编解码协议、高性能网络库
Kitex RPC框架
Kitex Core:核心组件 Kitex Byted:与公司内部基础设施集成 Kitex Tool:代码生成工具
网络库Netpoll
go原生网络库的弊端:
- 原生库无法感知连接状态:在使用连接池时,池中存在失效连接,影响连接池的复用。
- 原生库存在goroutine暴涨的风险:一个连接一个goroutine的模式,由于连接利用率低下,存在大量goroutine占用调度开销,影响性能。
Netpoll优势:
- 解决无法感知连接状态问题:引入epoll主动监听机制,感知连接状态
- 解决goroutine暴涨的风险:建立goroutine池,复用goroutine
- 提升性能:引入Nocopy Buffer,.向上层提供NoCopy的调用接口,编解码层面零拷贝
特性:
支持多协议,支持灵活的自定义协议的扩展
总结
- RPC框架主要三层:编解码层、通信协议层、网络传输层
- RPC框架性能指标:稳定性、可扩展性、高性能等
- Kitex RPC框架简介和Netpoll优势