分布式系统雪崩效应
雪崩效应
由于服务提供者A不可用,导致服务调用者B对A的请求阻塞,没有相关的机制通知或解决请求阻塞,导致在服务调用者B对A请求的阻塞越来越多,阻塞请求变多并且不断对A进行请求重试导致服务调用者B所在的系统的资源会被耗尽,而服务调用者B所在的系统可能并不会只有对A的调用,还有存在对其他服务提供者的调用,因为调用A把系统资源已经耗尽了,导致也无法处理对非A请求,而且这种不可用可能沿请求调用链向上传递,比如说服务调用者C会调用B的服务,因为B所在的系统不可用,导致C也不可用,这样级联导致阻塞请求越来越多,表现为多个系统都不可用了,这种现象被称为"雪崩效应"。
雪崩效应的详述
根据上面的描述,概括一下雪崩效应的过程:服务提供者不可用->服务调用者请求重试->服务调用者所在的系统资源耗尽,服务调用者不可用。
这个过程再概括一下分为三个阶段:
- 服务提供者不可用
- 服务调用者重试
- 服务调用者不可用
服务雪崩的每个阶段都可能由不同的原因造成,下面逐一说明。
服务提供者不可用
服务提供者不可用产生的原因可能有以下几点:
- 硬件故障
如服务器宕机,机房断电,光纤被挖断等。 - 程序Bug
如程序逻辑导致内存泄漏,JVM长时间FullGC等。 - 缓存击穿
缓存击穿一般发生在缓存应用重启, 所有缓存被清空时,以及短时间内大量缓存失效时. 大量的缓存不命中, 使请求直击后端,造成服务提供者超负荷运行,引起服务不可用. - 流量激增
流量激增导致服务提供者无法承受这样的高负载,激增的原因有异常流量,重试加大流量等。
服务调用者重试
在服务提供者出现不可用的情况下,服务调用者重试加大了流量,服务调用者重试又可以分为两种:
- 用户重试
在服务提供者不可用后,用户由于忍受不了界面上长时间的等待,而不断刷新页面甚至提交表单。 - 代码逻辑重试
在代码中请求远端服务时,在出现请求异常的时候,代码逻辑都会有重试的功能,这在因为网路抖动导致请求超时的情况下是很有用的。但是如果本身服务提供者就不可用了,这种不断地重试会加大对服务器提供者的请求流量。
服务调用者不可用
服务调用者不可用产生的原因主要是:
- 同步等待造成的资源耗尽
当服务调用者使用同步调用时,会产生大量的等待线程占用系统资源。一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态。
雪崩效应应对策略
应对策略从造成雪崩的原因出发,提供不同的原因下的解决方案。
- 硬件故障:多机房容灾、异地多活等。
- 程序BUG:修改程序bug、及时释放资源等。
- 缓存穿透:缓存预加载、缓存异步加载等。
- 流量激增:服务自动扩容、流量控制(限流、关闭重试)等。
- 同步等待:资源隔离、MQ解耦、不可用服务调用快速失败等。资源隔离通常指不同服务调用采用不同的线程池;不可用服务调用快速失败一般通过熔断器模式结合超时机制实现。
总结一下就是几个关键词:限流、熔断、扩容、隔离。
you are the best!