这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天
RPC框架初探
-
RPC调用需要解决的问题
- 函数映射
- 数据转换成字节流
- 网络传输
-
RPC概念模型
- RPC调用过程
-
RPC的好处
- 单一职责,有利于分工协作和运维开发
- 可扩展性强,资源使用率更优
- 故障隔离,服务的整体可靠性更高
-
RPC面临的挑战
- 服务宕机,对方应该如何处理?
- 在调用过程中发生网络异常,如何保证消息的可达性?
- 请求量突增导致服务无法及时处理,有哪些应对措施?
-
RPC框架结构
-
编解码层传递的数据形式
-
语言特定的格式
- 许多编程语言都内建了将内存对象编码为字节序列的支持,例如 Java 有 java.io.Serializable
- 方便但是不利于兼容性,导致语言和功能高度绑定,并且也不利于安全设计
-
文本格式
- JSON、XML、CSV 等文本格式,具有人类可读性
- 便于人类理解,但是由于数字的编码存在歧义,比如XML和CSV不能区分数字和字符串,JSON虽然区分字符串但是不区分整数和浮点数,而且json的序列化和反序列化有时还需要依赖反射,性能较差
-
二进制编码
- 具备跨语言和高性能等优点,常见有 Thrift 的 BinaryProtocol,Protobuf 等
- TLV编码和Varint编码
-
-
TLV编码形式(扩展性好,但是有type和length两个冗余字段)
-
编码选择的考量
- 兼容性:支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
- 通用性:支持跨平台、跨语言
- 性能:从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长
-
协议层数据包以及对应结构
- 网络通信层相关
-
往往使用网络库来代替复杂的socket编程,以下是网络库选择的考量
- 提供易用 API:封装底层 Socket API连接管理和事件分发
- 功能:协议支持: tcp、udp 和 uds 等优雅退出、异常处理等
- 性能:应用层 buffer 减少 copy,高性能定时器、对象池等
RPC框架的性能指标
-
常用指标:稳定性,易用性,扩展性,观测性,高性能
-
稳定性相关
- 长尾请求:往往是指调度时间明显高于均值的请求,业界关于延迟有一个常用的P99标准,认为末端的1%就可以视为长尾请求,在复杂的系统中长尾请求是不可避免的,可能是由于网络抖动,GC,系统调度等原因(往往使用超时重试解决)
-
易用性相关
- 开箱即用:合理的默认参数选项、丰富的文档
- 周边工具:生成代码工具、脚手架工具
-
扩展性相关
- 一次请求发起会先经过治理层面,治理的逻辑封装在中间件中,通过链式调用来自由调度
-
观测性相关
- Log、Metric、 Tracing,常见基本三件套
- 内置观测性服务(往往使用一个简单的HTTP请求解决)
-
高性能相关
字节自研Kitex
- 整体架构