美文网首页架构深度学习
3.6:服务熔断设计

3.6:服务熔断设计

作者: 今年花开正美 | 来源:发表于2020-05-22 22:51 被阅读0次

本文将梳理微服务架构下,服务熔断原理与设计。整体包含以下两部分:

  • 为什么需要服务熔断
  • Hystrix熔断的设计

为什么需要服务熔断

熔断场景

先定义两种角色,上游服务(服务调用方),下游服务(服务发布方)。一般而已,上游服务和下游服务是分开部署的,上游服务通过远程调用的方式来使用下游服务功能。

基于网络通信过程中的不确定性,有时上游服务调用下游服务可能出现如下四种情况:成功、失败、超时、拒绝。

在出现失败、超时、拒绝时,若不做处理,将有可能出现以下几种问题:

  1. 因单个服务故障导致系统雪崩,上游服务调用下游服务超时超时将增加请求的RT(Response Time),在系统高峰期请求将阻塞在上游服务进而导致上游服务也出现故障。
  2. 请求响应的结果是不可控的,用户收到的可能是超时、失败、拒绝等不可理解的错误信息。

因此在这种情况下,上游服务要有能力来对出现问题的下游服务进行熔断,也就是对有问题的下游服务不进行访问,而直接将将结果进行降级处理。

熔断设计

基于对场景的分析,可以知道熔断最基本的几个功能:

  1. 需要知道下游服务的调用结果。
  2. 可以根据调用结果判断是否开启熔断。
  3. 自定义降级内容,某个服务或接口开启熔断后,所有对该服务的请求都不在调用下游服务,而直接返回自定义的降级内容。
  4. 自动关闭熔断,下游服务不会一直处于故障状态,在下游恢复后需要能自动的关闭熔断。

下面我们就来看看Hystrix是怎么设计实现熔断的把。

Hystrix熔断的设计

Hystrix不仅仅是熔断器,他是专门用来保护服务调用过程中的各种问题。主要包括了服务线程池隔离,请求缓存,请求合并,以及最重要的熔断和降级。

本文重点分析熔断和降级的设计,其他内容请自行了解。

指标衡量工具:HystrixCommandMetrics

在Hystrix中,每一个Command对应一个断路器,每个断路器都有对应的HystrixCommandMetrics来负责结果统计、熔断的判断。

在HystrixCommandMetrics中最核心的功能就是维护了滑动时间窗口(t)内的若干个桶(n),每个桶统计(t/n)秒内的统计结果。默认t=1s,n=10。

熔断结果统计设计图

如上图所示,每个桶有四个统计值,分别是:

  • 当前时间窗口内请求总数量。
  • 当前时间窗口内请求失败数量。
  • 当前时间窗口内请求拒绝数量。
  • 当前时间窗口内请求超时数量。

断路器主要使用HystrixCommandMetrics下面两个方法来判断是否打开。

  • HystrixCommandMetrics.HealthCounts.getTotalRequests():请求总数
  • HystrixCommandMetrics.HealthCounts.getErrorPercentage():请求错误比例

<font color=red>
虽然HystrixCommandMetrics维护了一个滑动时间窗口内的n个桶数据,但是Hystrix却只使用了最新一个桶来作为判断的依据。
</font>

断路器:HystrixCircuitBreaker

HystrixCircuitBreaker是熔断实现的核心类,包括四个重要属性:

  • HystrixCommandProperties properties:断路器配置信息
  • HystrixCommandMetrics metrics:当前断路器维护的指标衡量工具
  • AtomicBoolean circuitOpen:熔断开关
  • AtomicLong circuitOpenedOrLastTestedTime:熔断开关打开时间或上一次探测时间

断路器的所有方法都是围绕上述四个属性来实现的,下面我们就详细分析下断路器的核心方法

allowRequest()

Hystrix在调用下游服务之前,首先调用该方法判断是否允许请求,若返回false,则直接走降级逻辑(Fallback)。

下面我们分析下allowRequest()的主要流程:

  1. 熔断开关是否强制打开,是则返回false,否则走下一步。

  2. 熔断开关是否强制关闭,是则返回true,但是返回true之前还是会调isOpen()走断路器的计算逻辑,用来模拟熔断打开/关闭行为。

  3. 调isOpen()和allowSingleTest()方法,这里代码(!isOpen() || allowSingleTest())有的拗口,总结下就两种情况:

    熔断开关是关闭时,则allowRequest()直接返回true,允许请求。
    熔断开关是打开的,则走allowSingleTest()逻辑,检查当前是否可以进行下一次探测了。
    

isOpen()

该方法专门用来判断断路器是否打开,具体流程如下:

  1. 熔断开关(circuitOpen)是否打开,也就是已经处于熔断状态了,则直接返回true。
  2. 获取最新一个统计桶。
  3. 判断请求总量是否小于设置的阈值,是则返回false。
  4. 判断错误率是否小于设置的阈值,是则返回false,否则进入下一步。
  5. 到这里说明需要打开熔断开关了,通过CAS来设置熔断开关为true。设置成功,则将circuitOpenedOrLastTestedTime设置为当前时间。
  6. 返回熔断开关为打开。

allowSingleTest()

该方法主要是在熔断开关打开的状态下,不断的在达到了探测时间时,临时放行一个请求到下游服务。主要就以下两步:

  1. 判断(circuitOpenedOrLastTestedTime+设置的探测时间)是否小于当前时间,是则说明已经可以进行下一次探测(临时放行这次请求)了。
  2. 在上一步为是时,重新更新circuitOpenedOrLastTestedTime的值,以供下次使用。

markSuccess()

在每次调用下游服务成功后,都调用该方法来将熔断开关关闭。主要以下两步:

  1. 若熔断开关是打开的,则将开关关闭。
  2. 重置指标衡量数据。

Hystrix的熔断设计还是比较清晰的,主要代码里面使用了大量的RxJava类库,不熟悉的话看代码还是比较吃力。

最后我们看下官方提供的熔断器判断流程图:

服务熔断设计流程图

相关文章

  • 3.6:服务熔断设计

    本文将梳理微服务架构下,服务熔断原理与设计。整体包含以下两部分: 为什么需要服务熔断 Hystrix熔断的设计 为...

  • 第四节 服务的降级、限流、熔断与灰度

    本章要点 服务降级设计 服务限流/熔断设计 服务灰度发布设计 1.服务降级设计 当服务器压力剧增的情况下,根据实际...

  • 第二章架构设计之技术实践篇(下)

    本章要点 分布式事务设计与实践 服务降级设计 服务限流/熔断设计 服务灰度发布设计 1.分布式事务设计与实践 分布...

  • SpringCloud-笔记10-Hystrix防雪崩利器

    服务降级 依赖隔离 服务熔断-监控(Hystrix Dashboard) 服务熔断 Hystrix Dashboard

  • hystrix

    hystrix 三个设计原则 资源隔离利用线程池实现,每个依赖服务最多耗尽自己线程池的资源 熔断器熔断器 命令模式...

  • 设计

    设计 服务熔断:当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调...

  • 什么是服务熔断?

    服务熔断会触发服务降级释意:服务熔断,类比保险丝达到最大服务访问后,直接拒绝访问,拉闸停电,然后调用服务降级方法并...

  • go-kit 微服务 服务熔断(hystrix-go 实现)

    go-kit 微服务 服务熔断(hystrix-go 实现) 对客户端请求login方法添加熔断 Hystrix ...

  • gateway hystrix超时熔断

    配置 定义熔断后fallback() 这种熔断只能针对服务网关调用后端服务接口超时才会生效,后端服务抛异常无效

  • 微服务 11: Sentinel的微服务 限流与 熔断降级(文末

    1:微服务限流? 2:什么是熔断降级? 3:需要进行熔断的服务的Pom文件(consumer 或者 provid...

网友评论

    本文标题:3.6:服务熔断设计

    本文链接:https://www.haomeiwen.com/subject/bpkhahtx.html