PC 框架核心指标
那么设置一个RPC 框架的主要注意什么呢,下面就是介绍主要的
- 一些中间件:熔断限流超时控制、负载均衡、重试、长尾连接
- 扩展性
- 观测性
- 高性能
注册中间件
保障策略
-
熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
被调用者没响应,调用方不断的请求,这时被调用者可以点开连接
一个服务A调用服务B时,服务B的业务逻辑又调用了服务C,而这时服务C响应超时了,由于服务B依赖服务C,C超时直接导致B的业务逻辑一直等待,而这个时候服务A继续频繁地调用服务B,服务B就可能会因为堆积大量的请求而导致服务宕机,由此就导致了服务雪崩的问题
-
限流:保护被调用方,防止大流量把服务压垮
当调用端发送请求过来时,服务端在执行业务逻辑之前先执行检查限流逻辑,如果发现访问量过大并目超出了限流条件,就让服务端直接降级处理或者返回给调用方一个限流异常
-
超时控制:避免浪费资源在不可用节点上,响应时间太长,调用方主动的去断开
当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,避免浪费资源
请求成功率
-
负载均衡:请求分发
-
重试:请求其他服务器
注意,因为重试有放大故障的风险,首先,重试会加大直接下游的负载。如下图,假设A服务调用B服务,重试次数设置为r(包括首次请求),当B高负载时很可能调用不成功,这时A调用失败重试B,B服务的被调用量快速增大,最坏情况下可能放大到r倍,不仅不能请求成功,还可能导致B的负载继续升高,甚至直接打挂。 防止重试风暴,限制单点重试和限制链路重试
解决长尾请求
正常的重传
不正常的重传与解决
长尾请求:是指明显高于均值的那陪部分占比较小的请求。业界关于延迟有一个常用的P99标准,P99单个请求响应耗时从小到大排列,顺序处于99%位置的值即为P99值,那后面这1%就可以认为是长尾请求在较复杂的系统中,长尾延时总是会存在。造成这个的原因非常多,常见的有网络料动,GC,系统调度
就是有1%可能会在一个特定的时间之外(重传的触发时间段t3),才会响应回来,这和正常的重传不同,原因详见
解决:直接定义重传到另一台服务器以获取到响应
我们预先设定一个阈值t3(比超时时间小,通常建议是RPC请求延时的pct99),当Rg1发出去后超过t3时间都没有返回,那我们直接发起重试请求Rq2,这样相当于同时有两个请求运行。然后等待请求返回,只要Resp1或者Rs印2任意一个返回成功的结果,就可以立即结束这次情求,这样整体的耗时就是t4,它表示从第一个请求发出到第一个成功结果返回之间的时间,相比于等待超时后再发出请求,这种机制能大大减少整体延时,
扩展性
- Middleware:middleware 会被构造成一个有序调用链逐个执行,比如服务发现、路由、负载均衡、超时控制等
- Option:作为初始化参数
- 核心层是支持扩展的:编解码、协议、网络传输层
- 代码生成工具也支持插件扩展
一次请求发起首先会经过治理层面,治理相关的逻辑被封装在middleware中,这些middleware会被构造成一个有序调用链逐个执行,比如服务发现、路由、负载均衡、超时控制等,mw执行后就会进入到Iremote模块,完成与远端的通信
观测性
-
三件套:
- Log:日志
- Metric:监控(如响应延迟)
- Tracing:顺着链路检查(如使用id对中间件、分层进行一个性能的分析)
-
内置观测性服务,用于观察框架内部状态
- 当前环境变量
- 配置参数
- 缓存信息
- 内置 pprof 服务用于排查问题
高性能
- 连接池和多路复用:复用连接,减少频繁建联带来的开销
- 高性能编解码协议:Thrift、Protobuf、Flatbuffer 和 Cap'n Proto 等
- 高性能网络库:Netpoll 和 Netty 等