雪崩问题
微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩
例如下图中,如果服务 D 挂掉了,那么服务 A 相应的调用服务 D 的业务会阻塞。而此时如果调用服务 D 的业务请求越来越多,就会使得服务 A 的资源被耗尽。这时即使服务 B 的业务可以正常运行,服务 A 调用服务 B 的业务也无法完成
在微服务较多且复杂时,这种雪崩问题会更加明显,会使得整个微服务瘫痪
解决雪崩问题的常见方式有四种:
1.超时处理
设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待
这种方式只能缓解雪崩问题,因为假设等待时间为 1s,因为一个服务内部对于请求的处理是串行的,所以此时就是一秒释放一个请求,但是如果进入的请求是每秒两个,那么资源终究还是会被消耗殆尽
2.舱壁模式
限定每个业务能使用的线程数,避免耗尽整个 tomcat 的资源,因此也叫线程隔离
将服务 A 的资源划分成一个又一个独立的线程池,此时假设服务 C 挂掉了,那么服务 A 中只有一个线程池的资源会被耗尽,不会导致所有的资源被耗尽。但这种方式下,资源还是会有一定的浪费
3.熔断降级
由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求
在上图中,如果出现熔断,那么访问服务 D 的请求就会被直接拦截,使得请求被快速释放,这样就不会导致资源被浪费
4.流量控制
限制业务访问的 QPS(每秒处理的请求数量Queries Per Second),避免服务因流量的突增而故障
这种方式是预防雪崩问题的发生,避免某个服务发生故障,防止这个微服务的故障传递到其他的微服务去。而前三种都是已经有服务发生故障了,要怎么去避免这个故障传递到其他服务
这种方式不能完全避免服务的故障,因为高并发只是引起服务故障的原因之一,还有其他的问题,例如网络问题,此时就要用到其他的解决方案
微服务保护技术对比
由于雪崩问题,我们需要使用到一些技术来对微服务进行保护,常见的服务保护技术有 Sentinel 和 Hystrix
二者的对比如下:
Sentinel | Hystrix | |
---|---|---|
隔离策略 | 信号量隔离 | 线程池隔离 / 信号量隔离 |
熔断降级策略 | 基于慢调用比例或异常比例 | 基于失败比率 |
实时指标实现 | 滑动窗口 | 滑动窗口(基于 RxJava) |
规则配置 | 支 |