1. Hystrix服务熔断

1.1 断路器

类似保险丝

1.2 熔断是什么

熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的相应信息。
当检测到该节点微服务调用响应正常后,恢复调用链路。

在Spring Cloud框架里,熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,
当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制,熔断机制的注解是@HystrixCommand。

大神论文:https://martinfowler.com/bliki/CircuitBreaker.html

1.3 修改cloud-provider-hystrix-payment8001

  • PaymentService
package com.lele.springcloud.service;import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.ribbon.proxy.annotation.Hystrix;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;import java.util.concurrent.TimeUnit;/*** @author: lele* @date: 2021/3/20 13:53* @description:*/
@Service
public class PaymentService {/*** 正常访问:肯定OK* @param id* @return*/public String paymentInfo_OK(Integer id) {return "线程池:" + Thread.currentThread().getName()+"  paymentInfo_OK,id:" + id+"\t"+"哈哈~";}@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="5000")})public String paymentInfo_TimeOut(Integer id) {//        int timeNumber = 5;
//         int age = 10/0;try {TimeUnit.MILLISECONDS.sleep(3000);} catch(InterruptedException e) {e.printStackTrace();}
//        return "线程池:"+ Thread.currentThread().getName()+"  paymentInfo_OK,id" + id+"\t"+"~~"+"耗时(秒)"+timeNumber;return "线程池:"+ Thread.currentThread().getName()+"  paymentInfo_OK,id" + id+"\t"+"哈哈~~"+"耗时(秒)";}public String paymentInfo_TimeOutHandler(Integer id) {return "线程池:"+Thread.currentThread().getName()+"  8001系统繁忙或者运行报错,请稍候再试,id: "+id+"\t"+"(╥╯^╰╥)";}//======服务熔断@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"),})public String paymentCircuitBreaker(@PathVariable("id") Integer id) {if (id < 0) {throw new RuntimeException("******id 不能负数");}String serialNumber = IdUtil.simpleUUID();return Thread.currentThread().getName()+"\t"+"调用成功,流水号:" + serialNumber;}public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) {return "id 不能为负数,请稍候再试,id:"+id;}
}
  • PaymentController 添加

1.4 测试

正确访问:http://localhost:8001/payment/circuit/1

错误访问:http://localhost:8001/payment/circuit/-1

多次错误,然后慢慢正确,发现刚开始不满足条件,就算是正确的访问地址也不能进行访问,需要慢慢的恢复链路

1.5 总结

大神结论:

熔断类型

  • 熔断打开:请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟则进入熔断状态
  • 熔断关闭:熔断关闭不会对服务进行熔断
  • 熔断半开:部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断。

官网断路器流程图

断路器在什么情况下开始起作用:

涉及到断路器的三个重要参数:快照时间窗、请求总数阈值、错误百分比阈值
1、快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒

2、请求总数阈值:在快照时间窗内,必须满足请求总数阈值才有资格熔断,默认为20,意味着在10秒内,如果该Hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。

3、错误百分比阈值:当请求总数在快找时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过了50%的错误百分比,在默认设定50%的阈值情况下,这时候会将断路器打开

断路器开启或者关闭的条件
1、当满足一定阀值的时候(默认10秒内超过20个请求次数)

2、当失败率达到一定的时候(默认10秒内超过50%请求失败)

3、到达以上阀值,断路器将会开启

4、当开启的时候,所有请求都不会进行转发

5、一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5

断路器打开之后
1、再有请求调用的时候,将不会调用主逻辑,而是直接调用降级fallback,通过熔断器,实现了自动的发现错误并将降级逻辑切换为主逻辑,减少响应延迟的效果。

2:、原来的主逻辑要如何恢复呢?
对于这一问题,Hystrix也为我们实现了自动恢复功能。
当断路器打开,对主逻辑进行熔断之后,Hystrix会启动一个休眠时间窗,在这个时间窗内如果此次请求正常返回,那么断路器将继续闭合,主逻辑恢复,如果这次请求依然有问题,断路器继续进入打开状态,休眠时间窗重新计时。

ALL配置

package com.liang.cloud;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;public class AllHystrixCommand {@HystrixCommand(fallbackMethod = "str. fallbackMethod",groupKey = "strGroupCommand",commandKey = "strCommarld",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. requestVolumeThreshold的情况下,如果错误请求数的百分比超过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"),//熔动时间窗没置,该时间用于断路器判断健康度时需要收集信息的持续时间@HystrixProperty(name = "metrics.rollingStats.timeinMilliseconds", value = "1000"),//该属性用来没置熔动时间窗统计指标信息时划分”桶"的数量,断路器在收集指标信息的时候会根据//设置的时间窗长度拆分成多个"桶”来累计各度量值,每个”桶" 记录了- -段时间内的来集指标。//比如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"),//该属性用来没置百分位统计滚动窗口中使用“桶@HystrixProperty(name = "metrics.rollingPercentile.numBuckets", value = "60000"),//该属性用来设置在执行过程中每个 “桶” 中保留的最大执行次数。如果在炫动时间窗内发生超过该没定值的执行次数,//就从最初的位置开始重写。例如,将该值设置为100,熔动窗口为10秒,若在10秒内一个“桶 ” 中发生了500次执行,//那么该“桶”中只保留最后的100次执行的统计。另外,增加该值的大小将会增加内存量的消耗,并增加排序百分位数所需的计算时间。@HystrixProperty(name = "metrics . rollingPercentile. bucketSize", value = "100"),//该属性用来没置采集影响断路器状态的健康快照(请求的成功、错误百分比) 的间隔等待时间。@HystrixProperty(name = "metrics.healthSnapshot.intervalinMilliseconds", value = "500"),//是否开启请求缓存@HystrixProperty(name = "requestCache.enabled", value = "true"),//HystrixProperty的执行和时间是否打印日志到HystrixRequestLog中@HystrixProperty(name = "requestLog.enabled", value = "true"),@HystrixProperty(name = "metrics.rollingPercentile.bucketSize", value = "10"),//该属性用来汝置采集影响断路器状态的健康快照(请求的成功、错误百分 比)的间隔等待时间。@HystrixProperty(name = "metrics.healthSnapshot.intervalinMilliseconds", value = "500"),//是否开启请求缓存@HystrixProperty(name = "requestCache.enabled", value = "true"),// HystrixCommand的执 行和事件是否打印日志到HystrixRequestLog中@HystrixProperty(name = "requestLog.enabled", value = "true"),},threadPoolProperties = {//该参数用来没置执行命令线程池的核心线程数,该值 也就是命令执行的最大并发量@HystrixProperty(name = "coreSize", value = "10"),//该参数用来没置线程池的最大队列大小。当设置为-1时,线程池将使用SynchronousQueue实现的队列,//否则将使用LinkedBlockingQueue 实现的队列。@HystrixProperty(name = "maxQueueSize", value = "-1"),//该参数用来为队列设置拒绝阙值。通过该参数,即使队列没 有达到最大值也能拒绝请求。//该参数主要是对LinkedBlockingQueue队列的补充,因为LinkedBlockingQueue//队列不能动态修改它的对象大小,而通过该属性就可以凋整拒绝请求的队列大小了。@HystrixProperty(name = "queueSizeRejectionThreshold", value = "5"),})public String All() {return "zhang";}
}

2. hystrix工作流程

官网:https://github.com/Netflix/Hystrix/wiki/How-it-Works

1 创建HystrixCommand(用在依赖的服务返回单个操作结果的时候)或HystrixObserableCommand(用在依赖的服务返回多个操作结果的时候)对象。
2 命令执行。其中HystrixCommand实现了下面前两种执行方式:而HystrixObserableCommand实现了后两种执行方式:execute():同步执行,从依赖的服务返回一个单一的结果对象,或是在发生错误的时候跑出异常。queue():异步执行,直接返回一个Future对象,其中包含了服务之行结束时要返回的单一结果对象。obserce():返回Observable对象,他代表了操作的多个结果,它是一个Hot Obserable(不论“事件源”是否有“订阅者”,都会在创建后对事件进行发布,所以对于Hot Observable 的每一个订阅者都有可能是从事件源的中途开始的,并可能只是看到了整个操作的局部过程。)toObserable():同样返回Obserable对象,也代表了操作的多个结果,但他返回的是一个Cold Observale(没有“订阅者”的时候并不会发布事件,而是进行等等待,直到有订阅者之后才发布事件,所以对于Cold Obserable的订阅者,他可以保证从一开始看到整个操作的全部过程)
3 若当前命令的请求缓存功能是被启用的,并且该命令缓存命中,那么缓存的结果会立即以Observable对象的形式返回。
4 检查断路器是否为打开状态,如果断路器是打开的,那么Hys不会执行命令,而是转接到fallback处理逻辑(第8步);如果断路器是关闭的,检查是否有可用资源来执行命令(第5步)
5 线程池/请求队列/信号量是否沾满。如果命令依赖服务的专有线程池和请求队列,或者信号量(不使用线程池的时候)已经被沾满,那么Hystrix也不会执行命令,而是转接到fallback处理逻辑(第8步)
6 Hystrix会根据我们编写的方法来决定采取什么样的方式去请求依赖服务,HystrixCommand.run();返回一个单一的结果,或者抛出异常,HystrixObservableCommand.construct():返回一个Observable对象来发射多个结果,或通过onError发送错误通知
7 Hystrix会将 成功 失败 拒绝 超时 等信息报告给断路器,而断路器会维护一组计数器来统计这些数据,断路器会使用这些统计数据来决定是否要讲断路器打开,来对某个依赖服务的请求进行熔断/短路
8 当命令执行失败的时候,Hystrix会进入fallback尝试回退处理,我们通常也称作该操作为‘服务降级’,而能够引起服务降级处理的情况有下面几种:第4步:当前命令处于熔断/短路状态,断路器是打开的时候。第5步:当前命令的线程池、请求队列或者信号量被沾满的时候。第6步:HystrixObservableCommand.construct或HystrixCommand.run();抛出异常的时候
9 当Hystrix命令执行成功之后,它会将处理结果直接返回或是以Observable的形式返回

如果我们没有为命令实现降级逻辑或者在降级处理逻辑中抛出了异常,Hystrix依然会返回一个Observable对象,但是他不会发射任何结果数据,而是通过onError方法通知命令立即中断请求,并通过onError()方法将因其命令失败的异常发送给调用者。

Spring Cloud(十一):Hystrix服务熔断-工作流程相关推荐

  1. Spring Cloud之Hystrix服务容错

    Spring Cloud之Hystrix服务容错 Hystrix的概述 Hystrix的使用 相关依赖 Eureka注册中心 服务提供者 服务消费者 执行测试 @HystrixCommand详解 服务 ...

  2. php如何做熔断降级,spring cloud 如何实现服务熔断服务降级

    Why 在微服务架构中,由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积.可能导致服务间延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障. 为了维 ...

  3. java 熔断机制_利用Spring Cloud实现微服务- 熔断机制

    2. 代码实现及验证 本次代码实现对RestTemplate和Feign两种微服务调用场景下,使用Hystrix验证Spring Cloud的熔断机制. 2.1 RestTemplate的微服务调用场 ...

  4. 【SpringCloud】Spring cloud Alibaba Sentinel 服务熔断

    1.概述 博客:https://www.bilibili.com/video/BV18E411x7eT?p=133&spm_id_from=pageDriver 本次案例结构图如下 新建2个项 ...

  5. 跟着狂神学SpringCloud(Rest环境搭建+Eureka服务注册与发现+ribbon+Feign负载均衡+Hystrix+服务熔断+Zuul路由网关+SpringCloud config分布)

    跟着狂神学SpringCloud SpringCloud 回顾之前的知识- JavaSE 数据库 前端 Servlet Http Mybatis Spring SpringMVC SpringBoot ...

  6. 《深入理解 Spring Cloud 与微服务构建》第十一章 服务网关

    <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 文章目录 <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 一.服务网关简介 二. ...

  7. Spring Cloud构建微服务架构:服务容错保护(Hystrix断路器)

    断路器 断路器模式源于Martin Fowler的Circuit Breaker一文."断路器"本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时," ...

  8. Spring Cloud中Hystrix、Ribbon及Feign的熔断关系是什么?

    导读 今天和大家聊一聊在Spring Cloud微服务框架实践中,比较核心但是又很容易把人搞得稀里糊涂的一个问题,那就是在Spring Cloud中Hystrix.Ribbon以及Feign它们三者之 ...

  9. java版电子商务spring cloud分布式微服务b2b2c社交电商:服务容错保护(Hystrix断路器)...

    断路器 断路器模式源于Martin Fowler的Circuit Breaker一文."断路器"本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时," ...

最新文章

  1. 针对Web应用的【攻击模式篇】
  2. STM32技术文档里面的I / O Level FT具体含义
  3. 送福利 | 送书3本 ASP.NET Core 真机拆解
  4. python 测试用例 自动生成目录_如何在python中自动将测试用例添加到测试套件中...
  5. atom上网本 安装linux,拆东墙补西墙?多数Atom上网本或将无法安装Windows 7
  6. BZOJ4247挂饰
  7. 数据结构之-冒泡排序
  8. 我眼中的几个测试认证(ISTQB/CSTQB/软件评测师)
  9. 央央家政:住家育儿嫂和月嫂的工作内容明细
  10. 关于INTERVAL 函数的使用
  11. 计算机第一次月考试题,计算机基础第一次月考试题.doc
  12. 向往的生活之鸿蒙传承,《向往的生活5》播放量破6.43亿,张艺兴功劳大,《跑男》比不了...
  13. Bandizip去除广告,注册图标,状态栏文本
  14. java-No route to host 解决办法
  15. 虚拟主机如何清空网站程序文件和mysql数据库数据
  16. 字王·百字工程·2016中秋纪念
  17. C8825D解锁步骤
  18. 2021年处暑是什么时候?处暑的习俗有哪些?
  19. Toad 使用快速入门(转贴)
  20. 计算机关系差运算与交运算的区别,计算机二级 公基础——关系运算.ppt

热门文章

  1. FreeRADIUS之RADIUSD说明
  2. 极简linux版本,4MLinux 26.0发布,这是一个极简版本
  3. error:Error parsing XML:unbound prefix
  4. 计算网络节点的平均度
  5. 同构和异构关系图-行人re_ID
  6. Android Market api
  7. Pytorch 的repeat函数
  8. windows的cmd常用命令
  9. 薅羊毛第三十八次更新
  10. requirejs的缺点