看看我是怎么样解决灾难性雪崩效应?

在微服务环境中,因为一个节点的故障而造成的其他节点的不可用的情况是比较常见的,这也就是我们常说的灾难性雪崩现象,而 Hystrix 给我们提供了解决这种情况的方案。

什么是灾难性的雪崩效应?

什么是灾难性的雪崩效应? 我们通过结构图来说明,如下

正常情况下各个节点相互配置,完成用户请求的处理工作

当某种请求增多,造成 "服务 T" 故障的情况时,会延伸的造成 "服务 U" 不可用,及继续扩展,如下

最终造成下面这种所有服务不可用的情况

这就是我们讲的灾难性雪崩

造成雪崩的原因可以归纳为以下三个:

  1. 服务提供者不可用 (硬件故障,程序 Bug,缓存击穿,用户大量请求)

  2. 重试加大流量 (用户重试,代码逻辑重试)

  3. 服务调用者不可用 (同步等待造成的资源耗尽)

最终的结果就是一个服务不可用,导致一系列服务的不可用,而往往这种后果是无法预料的。

如何解决灾难性雪崩效应?

我们可以通过以下 5 种方式来解决雪崩效应

1. 降级

超时降级、资源不足时 (线程或信号量) 降级,降级后可以配合降级接口返回托底数据。实现一个 fallback 方法, 当请求后端服务出现异常的时候, 可以使用 fallback 方法返回的值.

先来看下正常服务调用的情况

当 consumer 调用 provider 服务出现问题的情况下:

此时我们对 consumer 的服务调用做降级处理

2. 缓存

Hystrix 为了降低访问服务的频率,支持将一个请求与返回结果做缓存处理。如果再次请求的 URL 没有变化,那么 Hystrix 不会请求服务,而是直接从缓存中将结果返回。这样可以大大降低访问服务的压力。

Hystrix 自带缓存。有两个缺点:

  • 是一个本地缓存。在集群情况下缓存是不能同步的。

  • 不支持第三方缓存容器。Redis,memcache 不支持的。

3. 请求合并

在微服务架构中,我们将一个项目拆分成很多个独立的模块,这些独立的模块通过远程调用来互相配合工作,但是,在高并发情况下,通信次数的增加会导致总的通信时间增加,同时,线程池的资源也是有限的,高并发环境会导致有大量的线程处于等待状态,进而导致响应延迟,为了解决这些问题,我们需要来了解 Hystrix 的请求合并。

我们来演示下 Hystrix 中解决雪崩效应的第三种方式请求合并的实现

没有合并请求的场景

没有合并的场景中,对于 provider 的调用会非常的频繁,容易造成处理不过来的情况

合并请求的场景

什么情况下使用请求合并

在微服务架构中,我们将一个项目拆分成很多个独立的模块,这些独立的模块通过远程调用来互相配合工作,但是,在高并发情况下,通信次数的增加会导致总的通信时间增加,同时,线程池的资源也是有限的,高并发环境会导致有大量的线程处于等待状态,进而导致响应延迟,为了解决这些问题,我们需要来了解 Hystrix 的请求合并。

请求合并的缺点

设置请求合并之后,本来一个请求可能 5ms 就搞定了,但是现在必须再等 10ms 看看还有没有其他的请求一起的,这样一个请求的耗时就从 5ms 增加到 15ms 了,不过,如果我们要发起的命令本身就是一个高延迟的命令,那么这个时候就可以使用请求合并了,因为这个时候时间窗的时间消耗就显得微不足道了,另外高并发也是请求合并的一个非常重要的场景。

4. 熔断

当失败率 (如因网络故障 / 超时造成的失败率高) 达到阀值自动触发降级,熔断器触发的快速失败会进行快速恢复。

熔断其实是在降级的基础上引入了重试的机制。当某个时间内失败的次数达到了多少次就会触发熔断机制,具体的流程如下

5. 隔离
(线程池隔离和信号量隔离)

限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。

在应对服务雪崩效应时,除了前面介绍的降级,缓存,请求合并及熔断外还有一种方式就是隔离,隔离又分为线程池隔离和信号量隔离。接下来我们分别来介绍。

一、线程池隔离

1. 概念介绍

我们通过以下几个图片来解释线程池隔离到底是怎么回事

在没有使用线程池隔离时

当接口 A 压力增大,接口 C 同时也会受到影响

使用线程池的场景

当服务接口 A 访问量增大时,因为接口 C 在不同的线程池中所以不会受到影响

通过上面的图片来看,线程池隔离的作用还是蛮明显的。但线程池隔离的使用也不是在任何场景下都适用的,线程池隔离的优缺点如下:

优点

  1. 使用线程池隔离可以完全隔离依赖的服务 (例如图中的 A,B,C 服务),请求线程可以快速放回

  2. 当线程池出现问题时,线程池隔离是独立的不会影响其他服务和接口

  3. 当失败的服务再次变得可用时,线程池将清理并可立即恢复,而不需要一个长时间的恢复

  4. 独立的线程池提高了并发性

缺点  线程池隔离的主要缺点是它们增加计算开销 (CPU). 每个命令的执行涉及到排队,调度和上下文切换都是在一个单独的线程上运行的。


作者:波波烤鸭

链接:

https://blog.csdn.net/qq_38526573/article/details/91450807

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值