在微服务中由于服务间相互依赖很容易出现连锁故障,连锁故障可能是由于整个服务链路中的某一个服务出现故障,进而导致系统的其他部分也出现故障。例如某个服务的某个实例由于过载出现故障,导致其他实例负载升高,从而导致这些实例像多米诺骨牌一样一个个全部出现故障,这种连锁故障就是所谓的雪崩现象
比如,服务A依赖服务C,服务C依赖服务D,服务D依赖服务E,当服务E过载会导致响应时间变慢甚至服务不可用,这个时候调用方D会出现大量超时连接资源被大量占用得不到释放,进而资源被耗尽导致服务D也过载,从而导致服务C过载以及整个系统雪崩
![service_dependency](https://i-blog.csdnimg.cn/blog_migrate/f7a33779efeb10983ba2cf4ba31e890e.png)
某一种资源的耗尽可以导致高延迟、高错误率或者相应数据不符合预期的情况发生,这些的确是在资源耗尽时应该出现的情况,在负载不断上升直到过载时,服务器不可能一直保持完全的正常。而CPU资源的不足导致的负载上升是我们工作中最常见的,如果CPU资源不足以应对请求负载,一般来说所有的请求都会变慢,CPU负载过高会造成一系列的副作用,主要包括以下几项:
- 正在处理的(in-flight) 的请求数量上升
- 服务器逐渐将请求队列填满,意味着延迟上升,同时队列会用更多的内存
- 线程卡住,无法处理请求
- cpu死锁或者请求卡主
- rpc服务调用超时
- cpu的缓存效率下降
由此可见防止服务器过载的重要性不言而喻,而防止服务器过载又分为下面几种常见的策略:
- 提供降级结果
- 在过载情况下主动拒绝请求
- 调用方主动拒绝请求
- 提前进行压测以及合理的容量规划
今天我们主要讨论的是第二种防止服务器过载的方案,即在过载的情况下主动拒绝请求,下面我统一使用”过载保护“来表述,过载保护的大致原理是当探测到服务器已经处于过载时则主动拒绝请求不进行处理,一般做法是快速返回error
![fail_fast](https://i-blog.csdnimg.cn/blog_migrate/d05e38979e7d50394c73743bb9142a61.png)
很多微服务框架中都内置了过载保护能力,本文主要分析go-zero中的过载保护功能,我们先通过