雪崩问题及解决方案
什么是雪崩?
微服务调用调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。
如上图所示,由于某种原因发生故障,而其它依赖于该服务(服务D)的服务无法正常工作,从而导致这些服务也出现故障,这种连锁反应就称为雪崩效应。
解决雪崩问题的常见方式有四种:
超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待(如果释放的资源没有进入的快也只起缓解作用)
例如服务A依赖服务C如果服务C出现故障那么依赖于服务C的所有业务都会阻塞,所以服务A也就故障了。超时处理是怎么解决的?
它会在调用业务时加上一个超时时间,比如1秒钟,所以服务A依赖与服务C的业务最多等1秒,如果等待超过1秒,它会立即结束这个请求并提示给用户。
注意
如果释放的资源没有进入的快也只起缓解作用
舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离(资源浪费的情况)
如图:服务A里面的资源也就是tomcat其实看成整艘船,如何避免tomcat挂掉呢?
我们可以把tomcat里面的资源也就是线程,划分成一个一个独立的线程池,给每个业务分配一个线程池,例如业务1分配10个,业务2分配10个。业务1依赖于服务B,那它最多使用10个限制访问业务;同理访问业务2依赖与服务C,它也最多使用10个线程。如果服务C出现故障了,这个业务会阻塞占用我们的线程,但是它最多占用10个它使用的tomcat资源有限,所以就把这个故障隔离到了10个线程内了,因此这种线程也叫线程隔离。
注意
这种模式虽然解决了雪崩问题,但是存在资源上的浪费
熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。(能解决资源浪费的情况,这是一种比较好的方案)
熔断会去统计服务A里的业务,比方说,服务A里有一个业务是来访问服务D的,第一次是正常的,后面两次都出现了故障。这个时候断路器统计的异常比例超出阈值,这个时候就会出现熔断。一旦出现熔断
那么在服务A内部,还想要访问服务d的这个业务(也就是依赖与服务d的这个业务)就会被拦截无法访问服务器了,快速失败,1ms也不等,直接释放资源,知道服务D有问题后拒绝访问,这样不会存在资源浪费的情况
注意:先有熔断(下游服务有问题了触发熔断了一种系统保护的手段)后有降级(上游服务因为发送了熔断无法调用有问题的服务走降级的逻辑)
流量控制:限制业务访问的QPS(QPS:每秒钟处理的请求的数量),避免服务因流量的突增而故障。(预防雪崩)
比方说有一个微服务,它能承受的最大qps是2,也就是每秒钟最多处理两个请求,但是现在由无数的请求涌过来,这个服务会因为无法承受而雪崩。
所以我们要避免因为流量过高而引起故障,这个时候我们就要用到Sentinel。
它可以按照这个服务所能承受的一个频率去释放请求,这样就避免了它出现故障。将雪崩问题扼杀在了摇篮中,因此流量控制实质上是预防雪崩。
小结
如何避免因瞬间高并发流量而导致服务故障?
1.流量控制(预防雪崩)
如何避免因服务故障引起的雪崩问题?
1.超时处理(如果释放的资源没有进入的快也只起缓解作用)
2.线程隔离(资源浪费的情况)
3.降级熔断(能解决资源浪费的情况,这是一种比较好的方案)