微服务下的雪崩效应以及解决的方法

1. 雪崩效应

1.1 定义

在微服务架构中,出现一种链式的调用关系,比如:A调用B,B调用C,B调用C。当请求量较少时,上述的调用是不会出现问题的

但是,当某一个服务(A)突然遇到大量请求时,整个链条所有服务负载剧增。此时,除了A,B服务之外,还有其他要调用C服务的服务出现问题,从而导致所有的项目出现问题。这种情况就叫做灾难性的雪崩效应

1.2 原因

  • 服务提供者不可用,如:硬件故障,程序BUG,缓存击穿,并发请求量过大等
  • 重试流量加大,如:用户重试,代码重试逻辑等
  • 服务调用者不可用,如:同步请求阻塞造成的资源耗尽等

1.3 结果

雪崩效应最终的结果:服务链条种的某一个服务不可用,导致一系列的服务不可用,最终造成服务逻辑崩溃

2. 如何防治雪崩效应

2.1 降级

当资源不足时,用户发出的请求没有办法在一定的时间内得到回应。此时不应该再让其继续等待下去,而是对此次的请求进行降级处理

服务降级后,通过编写回调接口,实现回调方法,给前端返回托底数据(比如:弹窗提示等),让此次的请求结果以另一种结果和方式返回给前端
当请求后端微服务出现异常时,也可以使用 fallback 方法的返回值

其实下面提到的所有 fallbackMethod(回调方法) 都是降级

2.2 熔断

当失败率(如10次请求,5次失败)达到阀值,自动触发降级

熔断器触发的快速失败会进行快速恢复

由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种防护措施,也成为过载保护

2.2.1 特点

  • 熔断就是具有特定条件的降级
  • 保证服务出现问题后,整个项目还可以继续运行
  • 牺牲局部服务,保全整体系统稳定性的措施

2.2.2 降级和熔断的区别

  • 降级是每次都会去访问对应的服务,如果出现了超时或资源不足就执行回调方法,返回托底数据
  • 熔断是当达到失败率后,不会再次去访问以下的服务,直接返回托底数据

2.3 请求缓存

将数据存储在缓存里,每次访问先走缓存,缓存没有再去访问对应的服务获取数据

2.4 请求合并

当A服务调用B服务时,如果请求突然剧增,那么可以设置在一定时间内(比如每 5ms)将所有请求合并在一起,减少对B服务的负载

缺点:如果一个请求本来 5ms 就搞定了,但是现在必须等 10ms 看看有没有其他的请求一起,这样这一个请求就从原来的 5ms 变成了 15ms

所以在使用时,要先确定,是否是一个高延迟的命令,如果是的话,就可以用请求合并了,因为这个时候等待所花的时间与延迟的时间对比起来,显得微不足道

2.5 隔离

分为:线程池隔离信号量隔离
通过判断线程池或信号量是否已满,超出容量的请求直接降级,从而达到限流的效果

2.5.1 线程池隔离

没有线程池隔离的项目,所有接口都运行在一个线程池中,当某一个接口访问的压力变大或出现故障时,会导致资源耗尽从而影响到其他的接口的调用而引发雪崩效应

2.5.1.1 隔离前
2.5.1.2 隔离后
2.5.1.3 优点
  • 可以安全隔离依赖的服务,减少所依赖服务发生故障时的影响面
  • 当失败的服务再次变得可用时,线程池将清理并立即恢复,而不需要一个长时间的恢复
  • 独立的线程池也提高了并发性
2.5.1.4 缺点
  • 请求在线程池中执行,肯定会带来任务调度,排队和上下文切换带来的CPU开销
  • 因为涉及到跨线程,那么就存在 ThreadLocal 数据的传递问题,比如在主线程初始化的ThreadLocal变量,在线程池中无法获取

2.5.2 信号量隔离

每次调用线程,当前请求通过计数信号量进行限制,当信号量大于最大请求数时进行限制,调用 fallback 接口快速返回

但是信号量的调用是同步的,也就是说,每次调用都得阻塞调用方的线程,直到结果返回。这样就导致了无法对访问做超时处理,只能依靠调用协议超时,无法主动释放

2.5.3 总结

线程池隔离:

  • 请求线程和调用线程不是同一条线程
  • 支持超时,可直接返回
  • 支持熔断,当线程池到达 maxConcurrentRequests(最大请求数) 后,再请求会触发 fallback(回调) 接口进行熔断
  • 隔离原理:每个服务单独使用线程池
  • 支持同步和异步两种方式
  • 资源消耗大,大量的线程上下文切换、排队、调度等,容器造成及其负载高
  • 无法传递 Http Header
  • 请求并发大,耗时长(计算大,或操作关系型数据库)采用线程池隔离

信号量隔离:

  • 请求线程和调用线程是同一条线程
  • 不支持超时,但支持熔断,当信号量到达 maxConcurrentRequests(最大请求数) 后,再请求会触发 fallback(回调) 接口进行熔断
  • 隔离原理:通过信号量的计数器
  • 同步调用,不支持异步
  • 资源消耗小,只是一个计数器
  • 可以传递 Http Header
  • 请求并发大,耗时短(计算小,或操作缓存),采用信号量隔离

3. 相关解决技术

熔断器-Hystrix:https://github.com/Netflix/Hystrix
服务哨兵-Sentinel:https://sentinelguard.io/zh-cn/

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LF3_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值