服务雪崩+缓存雪崩+解决方案

一、服务雪崩

1、定义:
服务堆积在同一个线程池中,因为所有的请求都是同一个线程池进行处理,这时候如果在高并发情况下,所有的请求全部访问同一个接口,
这时候可能会导致其他服务没有线程进行接受请求,这就是服务雪崩效应效应。

2、原因:
a.某几个机器故障:例如机器的硬驱动引起的错误,或者一些特定的机器上出现一些的bug(如,内存中断或者死锁)。
b.服务器负载发生变化:某些时候服务会因为用户行为造成请求无法及时处理从而导致雪崩,例如阿里的双十一活动,若没有提前增加机器预估流量则会造服务器压力会骤然增大二挂掉。
c.人为因素:比如代码中的路径在某个时候出现bug

3、解决:4种:服务降级、服务熔断、服务隔离、限流模式、超时机制
a.服务降级:在高并发情况下,防止用户一直等待(返回一个友好的提示,直接给客户端,不会去处理请求,调用fallBack本地方法),目的是为了用户体验。 秒杀---当前请求人数过多,请稍后重试
b.服务熔断:熔断机制目的为了保护服务,在高并发的情况下,如果请求达到一定极限(可以自己设置阔值),如果流量超出了设置阈值,让后直接拒绝访问,保护当前服务。使用服务降级方式返回一个友好提示,服务熔断和服务降级一起使用。
熔断的设计主要参考了hystrix的做法,分为3个模块:熔断请求判断算法、熔断恢复机制、熔断报警
 (1)熔断请求判断机制算法:使用无锁循环队列计数,每个熔断器默认维护10个bucket,每1秒一个bucket,每个blucket记录请求的成功、失败、超时、拒绝的状态,默认错误超过50%且10秒内超过20个请求进行中断拦截。
 (2)熔断恢复:对于被熔断的请求,每隔5s允许部分请求通过,若请求都是健康的(RT<250ms)则对请求健康恢复。
 (3)熔断报警:对于熔断的请求打日志,异常请求超过某些设定则报警。
c.服务隔离2种方式:线程池隔离和信号量隔离
 (1)线程池隔离:每个服务接口,都有自己独立的线程池,每个线程池互不影响。 
 (2)信号量隔离:使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,当请求进来时先判断计数器的数值,若超过设置的最大线程个数则拒绝该请求,若不超过则通行,这时候计数器+1,请求返
回成功后计数器-1。
d.限流模式:上述都属于出错后的容错处理机制,而限流模式则可以称为预防模式。限流模式主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。这种模式不能解决服务依赖的问题,只能解决系统整体资源分配问题,因为没有被限流的请求依然有可能造成雪崩效应。
e.超时机制:超时分两种:请求的等待超时、请求运行超时
 (1)等待超时:在任务入队列时设置任务入队列时间,并判断队头的任务入队列时间是否大于超时时间,超过则丢弃任务。
 (2)运行超时:直接可使用线程池提供的get方法

二、缓存雪崩

1、定义:
由于原有缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期。所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。

                   缓存正常从Redis中获取

                                   缓存失效瞬间

2、解决:5种:加锁排队、设置过期标志更新缓存、不同key设不同的缓存失效时间、二级缓存、消息中间件
a.加锁排队(集群使用分布式锁,单机使用本地锁):在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许1个线程查询数据和写缓存,其他线程排队等待(集群分布式锁,单机本地锁)。减少服务器吞吐量,效率低。
注意:加锁排队只是为了减轻数据库的压力,并没有提高系统吞吐量。假设在高并发下,缓存重建期间key是锁着的,这是过来1000个请求999个都在阻塞的。同样会导致用户等待超时,这是个治标不治本的方法。
b.设置过期标志更新缓存:给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。
 (1)缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存;
 (2)缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60分钟。这样,当缓存标记key过期后,实际缓存还能把旧数据返回给调用端,直到另外的线程在后台更新完成后,才会返回新缓存。

                     加锁排队

          设置过期标志更新缓存


c.不同key设不同的缓存失效时间:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
d.二级缓存:A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期
e.消息中间件方式(推荐)
消息中间件 可以解决高并发。如果大量的请求进行访问时候,Redis没有值的情况,会将查询的结果存放在消息中间件中(利用了MQ同步特性)
 

转载:
服务雪崩产生原因及解决办法

解决或缓解服务雪崩的方案

缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题!

Redis雪崩效应以及解决方案

猜你喜欢

转载自blog.csdn.net/wuhuagu_wuhuaguo/article/details/104238099