这是我参与「第五届青训营 」伴学笔记创作活动的第3天
一、基本概念
1.1 远程函数调用(RPC-Remote Procedure Calls)
- 函数映射
- 数据转换成字节流
- 网络传输
1.2 RPC概念模型
五个模型组成:User、User-Stub、RPC-Runtime、Server-Stub、Server
主要是讲参数打包压缩后在网络传输,然后将结果返回
1.3 一次RPC的完整过程
- IDL文件(Interface description language):即描述接口文件,使得不同平台上运行的对象和用不同语言编写的程序可以相互通信。
- 生成代码:通过编译器工具把IDL文件转换成语言对应的静态库
- 编解码:解决跨语言数据交互的格式
- 通信协议:规范传输内容和格式,以及额外的元数据
- 网络传输:成熟网络库的TCP/UDP
1.4 好处 and 缺点
优点:
- 单一职责,有利于分工协作和运维开发
- 可扩展性强,资源使用率更优(底层复用)
- 故障隔离,服务整体可靠性更高
缺点:
- 基于网络传输,一旦网络异常,如何保证消息可达性?
- 服务器宕机,对方应如何处理?
- 请求量突增服务器无法及时处理
二、分层设计
2.1 编解码层
-
生成代码
- 基于IDL生成不同语言对应的代码
-
编码格式
-
语言特定格式
-
文本格式
-
二进制编码
-
TLV 编码:Thrift 使用 TLV 编码(Tag+Length+Value)
-
Varint 编码:Protobuf 使用 Varint 编码
-
-
-
如何选择编码格式:
- 兼容性:支持自动增加新字段,不影响老的服务
- 通用型:支持跨平台、跨语言,即使用人群多
- 性能:空间和时间(编码解码所需时间,编码后数据的大小)
2.2 协议层
-
消息切分
- 特殊结束符
- 变长协议:length+body,通常需要用定长的部分来描述长度
-
协议构造
- 以 Thrift 的 THeader协议为例讲解
- LENGTH: 数据包大小,不包含自身
- HEADER MAGIC: 标识版本信息,协议解析时候快速校验
- SEQUENCE NUMBER: 表示数据包的seqID可用于多路复用,单连接内递增
- HEADER SIZE: 头部长度,从第14个字节开始计算一直到 PAYLOAD前
- PROTOCOL ID: 编解码方式,有 Binary 和Compact 两种
- TRANSFORMID: 压缩方式,如 zlib 和 snappy
- INFO ID: 传递一些定制的 meta 信息
- PAYLOAD: 消息体
-
协议解析:
- MagicNumber(读取协议类型)->PayloadCodec(读取编码方式)->Payload(解码)
2.3 网络通信层
-
网络库
-
提供易用的API
-
功能:
- 协议支持:TCP、UDP等等
- 退出、异常处理等等
-
-
核心指标
- 吞吐高
- 延迟低
三、关键指标
3.1 稳定性
- 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
- 限流:保护被调用方,防止大流量把服务压垮(降级处理/返回限流异常)
- 超时控制:避免浪费资源在不可用节点上(超时主动停掉不太重要的业务) (以上三种都是快速返回,避免资源浪费在不可调用的请求上,也是服务降级的手段)
3.2 请求成功率
-
负载均衡
- 服务节点负载尽量均匀,而不是某些节点负载过大
-
重试(会加大直接下游的负载,有放大故障的风险) 防止重试风暴,限制单点重试和限制链路重试。
3.3 长尾请求
长尾请求一般是指明显高于均值的那部分占比较小的请求。业界关于延迟有一个常用的P99标准, P99 单个请求响应耗时从小到大排列,顺序处于99%位置的值即为P99值,那后面这1%就可以认为是长尾请求。在较复杂的系统中,长尾延时总是会存在。造成这个的原因非常多,常见的有网络抖动,GC,系统调度。
我们预先设定一个阈值 t3 (比超时时间小,通常建议是RPC请求延时的pct99),当Req1发出去后超过t3时间都没有返回,那我直接发起重试请求Req2,这样相当于同时有两个请求运行。然后等待请求返回,只要Resp1或者Resp2任意一个返回成功的结果, 就可以立即结束这次请求,这样整体的耗时就是t4,它表示从第一个请求发出到第一个成功结果返回之 间的时间,相比于等待超时后再发出请求,这种机制能大大减少整体延时。
3.4 注册中间件
3.5 易用性
- 开箱即用: 合理的默认参数选项、丰富的文档
- 周边工具: 生成代码工具、脚手架工具
Kitex使用Suite来打包自定义的功能,提供「一键配置基础依赖」的体验
- 生成服务代码脚手架
- 支持protobuf 和thrift
- 内置功能丰富的选项
- 支持自定义的生成代码插件
3.6 扩展性
- Middleware
- Option
- 编解码层
- 协议层
- 网络传输层
- 代码生成工具插件扩展
执行流程图:(黄色部分即为中间件)
3.7观测性
Log、Metric、Tracing
内置观测性服务
除了传统的Log、Metric、Tracing 三件套之外,对于框架来说可能还不够,还有些框架自身状态需要暴露出来,例如当前的环境变量、配置、Client/Server初始化参数、缓存信息等。
3.8 高性能
这里分两个维度,高性能意味着高吞吐和低延迟,两者都很重要,甚至大部分场景下低延迟更重要。
四、课程总结
- 从本地函数调用引出RPC的基本概念。
- 重点讲解了RPC框架的核心的三层,编解码层、协议层和网络传输层。
- 围绕RPC框架的核心指标,例如稳定性、可扩展性和高性能等,展开讲解相关的知识。
- 通过对kitex讲解,讲述了当前互联网公司自研RPC框架的原因,拓展技术视野