8.1 RPC框架分层设计
- RPC:远程函数调用
- 解决问题:函数映射、数据转换成字节流、网络传输
-
一次RPC的完整过程:
IDL(Interface description language) 文件:它通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以互相通信
生成代码:通过编译器工具把IDL文件转换成语言对应的静态库
编解码:从内存中表示到字节序列的转换称为编码,反之为解码,也叫做序列化和反序列化
通信协议:规范了数据在网络中传输的内容和格式
网络传输:通常基于TCP/UDP
-
RPC好处:
单一职责,有利于分工协作和运维开发
可扩展性强,资源使用率更优
故障隔离,服务的整体可靠性更高
-
RPC问题:
服务宕机,对方该如何处理?
如果调用过程发生网络异常,如何保证消息可达性?
请求量突增导致服务无法及时处理,如何应对?
8.2 RPC关键指标分析
构建一个RPC框架需要考虑哪些指标呢?需要考虑:稳定性、易用性、扩展性、观测性、高性能。
稳定性:
既然是稳定性,肯定要有保障策略,有以下几个策略:
-
熔断
- 保护调用方,防止调用的服务出现问题而影响到整个链路
-
限流
- 保护被调用方,防止大流量把服务压垮
-
超时控制
- 避免浪费资源在不可用节点上
从某种程度上讲超时、限流和熔断也是一种服务降级的手段 。
请求成功率:
提高请求成功率,要从负载均衡、重试方便出发。
在重试时,要防止重试风暴,限制单点重试和限制链路重试。
长尾请求:
长尾请求一般是指明显高于均值的那部分占比较小的请求。 业界关于延迟有一个常用的P99
标准, P99
单个请求响应耗时从小到大排列,顺序处于99%
位置的值即为P99
值,那后面这 1%就可以认为是长尾请求。在较复杂的系统中,长尾延时总是会存在。造成这个的原因非常多,常见的有网络抖动、GC
、系统调度。
注册中间件:
上面提到的是稳定性的措施和策略,那么如何把这些措施和错略进行串联起来呢?是通过中间件的形式。
易用性:
-
开箱即用
- 合理的默认参数选项、丰富的文档
-
周边工具
- 生成代码工具、脚手架工具
扩展性:
需要提供尽量多的扩展点,扩展点包括:
- 中间件
Option
、参数- 编解码层
- 协议层
- 网络传输层
- 代码生成工具插件扩展
观测性:
观测性可以方便追踪、排查问题,包括:Log
、Metric
、Tracing
。
除了传统的 Log
、Metric
、Tracing
三件套之外,对于框架来说可能还不够,还有些框架自身状态需要暴露出来,例如当前的环境变量、配置、Client/Server
初始化参数、缓存信息等。
高性能:
做到高性能,我们的目标是:高吞吐、低延迟。
衡量标准覆盖场景:
- 单机多机
- 单连接、多连接
- 单/多
client
、单/多Server
- 不同大小的请求包
- 不同请求类型:例如
pingpong
、streaming
等
要达到目标需要的手段:
- 连接池
- 多路复用
- 高性能编解码协议
- 高性能网络库