这是我参与「第五届青训营 」伴学笔记创作活动的第 17 天
这部分内容主要是对 RPC 框架的关键指标讲解。在我们的实际业务中,不管是什么框架都会有对应的指标进行评价。通过关键指标的评比才能知道这个框架是否可行,以及相对于其他框架自己的优势在哪里。
3 关键指标
3.1 稳定性 - 保障策略
- 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
- 限流:保护被调用方,防止大流量把服务压垮
- 超时控制:避免浪费资源在不可用节点上
接下来详细接介绍一下:
熔断
:一个服务A调用服务B时,服务B的业务逻辑又调用了服务C,而这时服务C响应超时了,由于服务B依赖服务C,C超时直接导致B的业务逻辑一直等待,而这个时候服务A继续频繁的调用B,服务B就可能会因为堆积大量的请求而导致服务宕机,由此导致了服务雪崩的问题。限流
:当调用端发送请求过来时,服务端在执行业务逻辑之前先执行检查限流逻辑,如果发现访问量过大并且超出了限流条件,就让服务端直接降级处理或者返回给调用方一个限流异常- 超时:当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,避免浪费资源
超时、限流和熔断
都是一种服务降级的手段
3.2 稳定性 - 请求成功率
负载均衡和重试
重试有放大故障的风险,首先重试会加大直接下游的负载。在上图中,假设A服务调用B服务,重试次数设置而r包含首次请求,当B高负载时很可能嗲用不成功,这是A调用失败重试B,B服务的被调用量快速增大,最坏情况下可能放大到r倍,不仅不能请求成功,还可能导致B的负载继续升高,甚至直接挂掉。 防止重试风暴:限制单点重试和限制链路重试。
3.3 稳定性 - 长尾请求
长尾请求一般是指明显高于均值的那部分占比较小的请求。业界关于延迟有一个常用的P99标准,P99单个请求响应耗时从小到大排列,顺序处于99%的位置的值即为P99值,那后面这1%就可以认为是长尾请求。在较复杂的系统中,长尾延时总是会存在,造成这个原因非常多,常见的有网络抖动,GC,系统调度
我们先设定一个阈值t3(比超时时间小,通常建议是RPC请求延时的pct99),当Req1发出去超过t3时间都没有返回,那么直接发起重试请求 Req2,这样相当于同时有两个请求运行,然后等待请求返回,只要 Resp1 或者Resp2 任意一个返回成功的结果,就可以立即结束这次请求,这样整体的耗时就是t4,它表示从第一个请求发出到第一个成功结果返回之间的时间,相比于等待超时再发出请求,这种机制大大减少整体延时。
3.4 稳定性 - 注册中间件
Kitex Client 和 Server 的创建接口均采用Option模式,提供了极大的灵活性,很方便就能注入这些稳定性策略。
3.5 易用性
- 开箱即用:合理的默认参数选项、丰富的文档
- 周边工具:生成代码工具、脚手架工具
3.6 扩展性
- Middleware
- Option
- 编解码层
- 协议层
- 网络传输层
- 代码生成工具插件扩展
一次请求发起首先会经过治理层面,治理相关的逻辑被封装在middleware中,这些middleware会被构造成一个有序调用链逐个执行,比如服务发现、路由、负载均衡、超时控制等,mw执行后就会进入到remote模块,完成与远端的通信。
3.7 观测性
除了传统的Log、Metric、Tracing三件套外,还有些框架自身状态需要暴露出来,例如当前的环境变量、配置、Client/Server初始化参数、缓存信息等
3.8 高性能
- 场景
- 单机多机
- 单连接多连接
- 单/多 Client 单/多 Server
- 不同大小的请求包
- 不同请求类型:例如pingpong、streaming等
- 目标
- 高吞吐
- 低延迟
- 手段
- 连接池
- 多路复用
- 高性能编解码协议
- 高性能网络库
总结
- 框架通过中间件来注入各种服务治理策略,保障服务的稳定性
- 通过提供合理的默认配置和方便的命令行工具可以提升框架的易用性
- 框架应当提供给丰富的扩展点,例如核心的传输层和协议层
- 观测性除了传统的Log、Metric和Tracing之外,内置状态暴露服务也很有必要
- 性能可以从多个层面去优化,例如选择高性能的编解码协议和网络库