RPC的高可用存在几个方向:Load Balancing负载均衡、Rate Limiting限流、Load Shedding熔断、Graceful Degradation优雅退化、Latency and Deadlines延迟和死线
Load Balancing负载均衡
负载均衡核心目标其实主要是俩类:首先是减少负载、其次是提高可用性。
减少负载首先是分摊流量、并做到均匀分发,而可用性则是减少错误数、更低的延迟、并支持弹性。
而在这目标背后有很多障碍,对于每个请求的处理成本不同,第二是物理环境有差异,包括CPU性能差异以及邻居间互相影响。包括性能因素,中间例如JIT的预热、批量任务、大型GC导致性能出现问题。
在解决这些背景的核心问题是活跃的请求数量不代表后端容量,CPU更好的处理的更多,而大集群最终退化成随机选择。而每个客户端的活跃请求不包括其他客户端发完一个后端的请求,导致容易缺少全局视角,且最闲的轮询容易引发惊群效应。
方案
用于解决负载均衡有各种各样的方案设计
P2C方案,作为一个实现简单、负载均衡器的CPU成本低、请求分布好、O(1)的复杂度。Power of Two Choices方式是我们常见的做法。比如说现在有多个机房,因为线上的集群是多个,比如100个机器一个集群,我们正常把20个放到一个机房,一般要5个机房,就可以做到同城的多机房容灾。
对于这种情况以前的做法是需要在配置里面加zone,弄清楚这个机器的节点属于哪个zone,做一些复杂的配置去管理这个请求该去哪儿访问,通过这种方式就能比较好的进行规避。
比如说图里的A节点访问其它节点模拟了2ms的延迟,它可以比较好的把更多的请求放到本机房里,同时也确保本机房请求过多或延迟过高时会动态调度到其他的机房,这是一个动态的平衡。这里放了三个节点演示,通过数学的方式比较好的把多机房balance解决掉,而不需要用复杂的配置来完成这件事。
基于client统计指标调度
在client侧可以通过采集三类信息来进行均衡判断:Health、连接或特定的错误比率,Latency:请求的耗时,Inflight:当前正在运行的请求数量。通过三者来判断当前的server端是否正常已经进行相关的权重调节。
同时还存在基于server统计指标进行调度,其中利用类似于Actively:利用healthcheck同步;Passively:每次rpc response同步,CPU:百ms内的Moving Average 这类指标供均衡判断。
同时,为了保证数据的可用性,需要对相关计算分数进行衰减处理。
影响
负载均衡的策略执行后,很容易出现的影响是服务器之间的流量差异逐步放大,较慢的服务器接收的流量更少,从而容易导致abtest实验准确性,同时问题机器更难被监控发现