熔断机制概述
熔断机制是应对雪崩效应额一种微服务链路保护机制. 当扇出链路的某个微服务出错不可用或者响应时间太长, 会进行服务的降级, 进而熔断该节点微服务的调用, 快速返回错误的响应信息.
当检测到该节点微服务调用响应正常后, 恢复调用链路.
在 Spring Cloud 框架里, 熔断机制通过 Hystrix 实现. Hystrix 会监控微服务间调用的情况, 当失败的调用到一定阈值, 缺省是 5 秒内 20 次调用失败, 就会启动熔断机制, 熔断机制的注释是 @HystrixCommand
- @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
- @HystrixProperty(name = "circuitBreaker.enabled",value = "true"), // 是否开启断路器
- @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), // 请求次数
- @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期
- @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60") // 失败率达到多少后跳闸
- })
熔断类型
熔断打开
请求不在进行调用当前服务, 内部设置时钟一般为 MTTR(平均故障处理时间), 当打开时长达到所设时钟则进入半熔断状态
熔断关闭
熔断关闭不会对服务进行熔断
熔断半开
部分请求根据规则调用当前服务, 如果请求成功且符合规则则认为当前服务恢复正常, 关闭熔断
涉及到断路器的三个重要参数: 快照时间窗, 请求总数阈值, 错误百分比阈值.
1, 快照时间窗: 断路器确定是否打开需要统计一些请求和错误数据, 而统计的时间范围就是快照时间窗, 默认为最近的 10 秒.
2, 请求总数阈值: 在快照时间窗内, 必须满足请求总数阈值才有资格熔断. 默认为 20, 意味着在 10 秒内, 如果该 hystrix 命令的调用次数不足 20 次, 即使所有的请求都超时或其他原因失败, 断路器都不会打开
3, 错误百分比阈值: 当请求总数在快照时间窗内超过了阈值, 比如发生了 30 次调用, 如果在这 30 次调用中, 有 15 次发生了超时异常, 也就是超过了 50% 的错误百分比, 在默认设定 50% 阈值情况下, 这时候就会将断路器打开.
- //==========ALL
- @HystrixCommand(fallbackMethod = "str_fallbackMethod",
- groupKey = "strGroupCommand",
- commandKey = "strCommand",
- threadPoolKey = "strThreadPool",
- commandProperties = {
- // 设置隔离策略, THREAD 表示线程池 SEMAPHORE 信号池隔离
- @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"),
- // 当隔离策略选择信号池隔离的时候, 用来设置信号池的大小(最大并发数)
- @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests",value = "10"),
- // 配置命令执行的超时时间
- @HystrixProperty(name = "execution.isolation.thread.timeoutinMilliseconds",value = "10"),
- // 是否启用超时时间
- @HystrixProperty(name = "execution.timeout.enabled",value = "true"),
- // 执行超时的时候是否中断
- @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeOut",value = "true"),
- // 执行被取消的时候是否中断
- @HystrixProperty(name = "execution.isolation.thread.interruptOnCancel",value = "true"),
- // 允许回调方法执行的最大并发数
- @HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests",value = "10"),
- // 服务降级是否启用, 是否执行回调函数
- @HystrixProperty(name = "fallback.enabled",value = "true"),
- // 是否启用断路器
- @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
- // 该属性用来设置滚动时间窗中, 断路器熔断的最小请求数. 例如, 默认该值为 20 的时候,
- // 如果滚动时间窗(默认 10 秒) 内仅收到了 19 个请求, 即使这 19 个请求都失败了, 断路器也不会打开
- @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "20"),
- // 该属性用来设置在滚动时间窗中, 表示在滚动时间窗中, 在请求数量超过
- // circuitBreaker.requestVlomeThreshold 的情况下, 如果错误请求数的百分比超过 50,
- // 就把断路器设置 为 "打开" 状态, 否则就设置为 "关闭" 状态
- @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
- // 该属性用来设置当断路器打开之后的休眠时间窗, 休眠时间窗结束之后,
- // 会将断路器置为 "半开" 状态, 常识熔断的请求命令, 如果依然失败就将断路器继续设置为 "打开" 状态,
- // 如果成功就设置为 "关闭" 状态
- @HystrixProperty(name = "circuitBreaker.sleepWindowinMilliseconds",value = "5000"),
- // 断路器强制打开
- @HystrixProperty(name = "circuitBreaker.forceOpen",value = "false"),
- // 断路器强制关闭
- @HystrixProperty(name = "circuitBreaker.forceClosed",value = "false"),
- // 滚动时间窗设置, 该时间用于断路器判断健康度时需要收集信息的持续时间
- @HystrixProperty(name = "metrics.rollingStats.timeinMilliseconds",value = "10000"),
- // 该属性用来设置滚动时间窗统计指标信息时划分 "桶" 的数量, 断路器在手机指标信息的时候会根据
- // 设置的时间窗长度拆分为多个 "桶" 来累计各度量值, 每个 "桶" 记录了一段时间内的采集指标
- // 比如 10 秒内 拆分成 10 个 "桶" 收集这样, 所以 timeinMilliseconds 必须能被 numBuckets 整除 , 否则就抛异常
- @HystrixProperty(name = "metrics.rollingStats.numBuckets",value = "10"),
- // 该属性用来设置对命令执行的延迟是否使用百分位数来跟踪和计算, 如果设置为 false, 那么所有的概要统计都将返回 -1
- @HystrixProperty(name = "metrics.rollingPercentile.enabled",value = "false"),
- // 该属性用来设置百分位统计滚动窗口的持续时间, 单位毫秒
- @HystrixProperty(name = "metrics.rollingPercentile.timeinMilliseconds",value = "60000"),
- // 该属性用来设置百分位统计滚动窗口使用 "桶" 的数量 默认值是 6
- @HystrixProperty(name = "metrics.rollingPercentile.numBuckets",value = "6"),
- // 注意 timeinMilliseconds 和 numBuckets 保持整除关系
- // metrics.rollingPercentile.bucketSize: 该属性用来设置在执行过程中 每个 "桶" 中保留的最大执行次数. 如果在滚动时间窗内发
- // 生超过该设定值的执行 次数, 就从最初的位置开始重写. 例如, 将该值设置为 100, 滚动窗口为 10 秒,
- // 若 在 10 秒内一个 "桶" 中发生了 500 次执行, 那么该 "桶" 中只保留 最后的 100 次执 行的统计.
- // 另外, 增加该值的大小将会增加内存量的消耗, 并增加排序百分位数所 需的计算时间.
- @HystrixProperty(name = "metrics.rollingPercentile.bucketSize",value = "120")
- // 该属性用来设置采集影响断路器状态的健康快照 (请求的成功, 错误百分比) 的间隔等待时间
- @HystrixProperty(name = "metrics.healthSnapshot.intervalinMilliseconds",value = "600"),
断路器开启或者关闭的条件
当满足一定的阈值的时候(默认 10 秒内超过 20 个请求次数)
当失败率达到一定的时候(默认 10 秒内超过 50% 的请求失败)
到达以上阈值, 断路器将会开启
到开启的时候, 所有的请求都不会进行转发
一段时间之后(默认是 5 秒), 这个时候断路器是半开状态, 会让其中一个请求进行转发. 如果成功, 断路器会关闭, 若失败继续开启, 重复 4 和 5
熔断打开之后:
1. 再有请求调用的时候, 将不会调用主逻辑, 而是直接调用降级 fallback. 通过断路器, 实现了自动地发现错误并将降级逻辑切换为主逻辑, 减少响应延迟的效果.
2. 原来的主逻辑要如何恢复?
对于这点, hystrix 也为我们实现了自动恢复功能, 当断路器打开, 对主逻辑进行熔断之后, hystrix 会启动一个休眠时间窗, 在这个时间窗内, 降级逻辑是临时的成为主逻辑, 当休眠时间窗到期, 断路器将进入半开状态, 释放一次请求到原来的主逻辑上, 如果此次请求正常返回, 那么断路器将继续 闭合, 主逻辑恢复, 如果这次请求依然有问题, 断路器继续进入打开状态, 休眠时间窗重新计时.
来源: http://www.bubuko.com/infodetail-3496865.html