• 【云原生】springcloud11——Hystrix是怎样让微服务“易凡峰顺”的


    在这里插入图片描述

    前 言
    🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端
    ☕专栏简介:深入、全面、系统的介绍springcloud与springcloud Alibaba微服务常用技术栈
    🌰 文章简介:本文将介绍HyStrix服务熔断、降级,建议收藏备用,创作不易,敬请三连哦
    🥒文章推荐:
    微服务架构与springcloud 01——微服务入门
    微服务架构与springcloud02——父工程构建及支付模块实现
    微服务架构与springcloud03——项目热部署与消费者订单模块
    微服务架构与springcloud04——Eureka服务注册与发现
    springcloud05——Zookeeper实现支付微服务
    【云原生】springcloud06——订单服务注册zookeeper
    【云原生】springcloud07—Consul的服务注册与发现
    【云原生】springcloud08——Ribbon负载均衡调用
    【云原生】springcloud09——但愿发长久,空手撕Ribbon
    【云原生】springcloud10——人生苦短,我用OpenFeign

    1 Hystrix简介

    1.1 分布式系统面临的问题

    在这里插入图片描述

    在这里插入图片描述

    1.2 Histrix是什么

    在这里插入图片描述

    1.3 Hystrix能做什么

    服务降级、服务熔断,接近实时监控。

    官方文档:https://github.com/Netflix/Hystrix/wiki

    1.4 停更运维

    在这里插入图片描述
    后面我们会介绍代替的方案,但是必须先学习Hystrix了解其思想。

    2.Hystix的重要概念

    2.1 服务降级

    在这里插入图片描述

    概念:服务降级一般是指在服务器压力剧增的时候,根据实际业务使用情况以及流量,对一些服务和页面有策略的不处理或者用一种简单的方式进行处理,从而 释放服务器资源的资源以保证核心业务的正常高效运行。

    原因: 服务器的资源是有限的,而请求是无限的。在用户使用即并发高峰期,会影响整体服务的性能,严重的话会导致宕机,以至于某些重要服务不可用。故高峰期为了保证核心功能服务的可用性,就需要对某些服务降级处理。可以理解为舍小保大

    应用场景: 多用于微服务架构中,一般当整个微服务架构整体的负载超出了预设的上限阈值(和服务器的配置性能有关系),或者即将到来的流量预计会超过预设的阈值时(比如双11、6.18等活动或者秒杀活动)

    总结:服务降级是舍小保大,释放服务器资源的资源以保证核心业务的正常高效运行。

    2.2 服务熔断

    熔断这一概念来源于电子工程中的断路器(Circuit Breaker)。

    在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。

    这种牺牲局部,保全整体的措施就叫做熔断。

    总结:服务熔断相当于断闸

    ❤服务降级与服务熔断的区别
    1.触发原因不一样,服务熔断由链路上某个服务引起的,服务降级是从整体的负载考虑
    2.管理目标层次不一样,服务熔断是一个框架层次的处理,服务降级是业务层次的处理
    3.实现方式不一样,服务熔断一般是自我熔断恢复,服务降级相当于人工控制
    4.触发原因不同 服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
    总结:服务熔断是应对系统服务雪崩的一种保险措施,给出的一种特殊降级措施。而服务降级则是更加宽泛的概念,主要是对系统整体资源的合理分配以应对压力。

    2.3服务限流

    限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳定运行,一旦达到的需要限制的阈值,就需要限制流量并采取一些措施以完成限制流量的目的。比如:延迟处理,拒绝处理,或者部分拒绝处理等等

    在这里插入图片描述

    总结:服务限流相当于排队

    3 Hystrix微服务构建

    3.1 准备工作

    前面我们使用的都是Eureka集群,为了简化后面的测试、编码工作,避免每次启动的微服务数量过多(方便学习演示),我们暂时将7001的application.yml改造下,改成单机环境。
    在这里插入图片描述

    3.2 建项目

    新建项目cloud-provider-hystrix-payment8001
    在这里插入图片描述

    3.3 写pom

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-hystrixartifactId>
        dependency>
        
        <dependency>
            <groupId>com.wangzhou.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>${project.version}version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        
        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-allartifactId>
            <version>5.1.0version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    3.4 写yml

    server:
      port: 8001
    
    spring:
      application:
        name: cloud-provider-hystrix-payment
    
    eureka:
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          #单机版
          defaultZone: http://localhost:7001/eureka
          #集群版
    #      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.5 主启动

    @SpringBootApplication
    @EnableEurekaClient
    public class PaymentHystrixMain8001 {
        public static void main(String[] args) {
             SpringApplication.run(PaymentHystrixMain8001.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.6 业务类

    (1)Service
    节约时间,我们就不写接口了。

    @Service
    public class PaymentService {
    
        // 正常访问
        public String paymentInfo_OK(Integer id){
            // Hystrix底层调用的是Tomcat的线程池,我们在这里将线程名放回
            return "线程:  "+Thread.currentThread().getName()+"  paymentInfo_OK, id = "+id;
        }
    
        //超时访问
        public String paymentInfo_Timeout(Integer id) throws InterruptedException {
            int timeout = 3;
            // Hystrix底层调用的是Tomcat的线程池,我们在这里将线程名放回
            TimeUnit.SECONDS.sleep(timeout);
            return "线程:  "+Thread.currentThread().getName()+"  paymentInfo_OK, id = "+id + "\t" + "耗时"+ timeout +"s";
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    (2)Controller

    @RestController
    @Slf4j
    public class PaymentController {
    
        @Resource
        private PaymentService paymentService;
    
        @Value("${server.port}")
        private String serverPort;
    
        @GetMapping("/payment/hystrix/ok/{id}")
        public String paymentOk(@PathVariable("id")Integer id) {
            String result = paymentService.paymentInfo_OK(id);
            log.info("result:" + result);
            return result;
        }
    
        @GetMapping("/payment/hystrix/timeout/{id}")
        public String paymentInfo_timeout(@PathVariable("id") Integer id) throws InterruptedException {
            String result = paymentService.paymentInfo_Timeout(id);
            log.info("********* RESULT:"+ result +"***********");
            return result;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3.7 测试

    启动7001,8001两个微服务。

    访问:http://localhost:7001/,可用看到带熔断的8001Hystrix微服务。
    在这里插入图片描述
    访问ok接口

    http://localhost:8001/payment/hystrix/ok/1

    没毛病。
    在这里插入图片描述
    timeout接口。
    在这里插入图片描述
    在这里插入图片描述

    4 JMeter高并发测试

    直到目前为止,一切都是"易凡峰顺"的,来点异常场景。

    4.1 JMeter简介

    JMeter是开源软件Apache基金会下的一个性能测试工具,用来测试部署在服务器端的应用程序的性能。近来,JMeter因为其使用简单,现在也被社区作为接口测试工具… 举个栗子,你开了一个网店,兴冲冲地准备双十一大干一把,没想当天活动的时候大量用户一访问你的网店,你的网店挂了,那怎么办?办法就是在实际搞活动之前,先测试一下以确认系统能承受那么多的用户,当然测试的时候我们不需要请真正的这么多实际用户,否则得花多少钱啊,JMeter就是那个能帮助模拟大量用户访问你网站的一个软件。

    在这里插入图片描述

    4.2 下载、安装JMeter

    JMeter下载地址:http://jmeter.apache.org/download_jmeter.cgi

    在这里插入图片描述

    下载后解压到你系统下的任意目录,然后运行%JMETER_HOME%\bin\jmeter.bat文件

    4.3 JMeter压力测试

    新建测试计划,鼠标右键点击计划设置200*100 = 20000并发量。
    在这里插入图片描述
    新增http请求。
    在这里插入图片描述
    配置如下。
    在这里插入图片描述
    保存,启动压测。

    后台不断地看到接收到的请求。
    在这里插入图片描述

    这个时候你访问:http://localhost:8001/payment/hystrix/ok/1
    发现也开始转圈圈了,访问速度肉眼可见变慢。

    这是因为tomcat的默认工作线程被占满了,没有多余的线程来分解压力和处理了。

    如果此时外部消费者80也来访问,只能干等,最终导致消费者80不满意。8001被拖死。

    5 客户端测试集成

    5.1 建项目

    新建cloud-consumer-feign-hystrix-order80(一般将Hystrix用于客户端,但其实她也可以应用于服务端)

    在这里插入图片描述

    5.2 写pom

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-hystrixartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        
         <dependency>
                <groupId>com.wangzhou.springcloudgroupId>
                <artifactId>cloud-api-commonsartifactId>
                <version>${project.version}version>
         dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    5.3 写yml

    server:
      port: 80
    
    eureka:
      client:
        register-with-eureka: false
        service-url:
          defaultZone: http://localhost:7001/eureka
    
    #需要加上,否则会报错
    ribbon:
      ReadTimeout: 4000
      ConnectTimeout: 4000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5.4 主启动

    @SpringBootApplication
    @EnableFeignClients
    @EnableEurekaClient
    public class OrderHystrixMain80 {
        public static void main(String[] args) {
            SpringApplication.run(OrderHystrixMain80.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.5 业务类

    (1)service

    @Component
    @FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
    public interface PaymentHystrixService {
    
        @GetMapping("/payment/hystrix/ok/{id}")
        public String paymentOk(@PathVariable("id")Integer id);
        
        @GetMapping("/payment/hystrix/timeout/{id}")
        public String paymentInfo_timeout(@PathVariable("id") Integer id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    (2)Controller

    @Slf4j
    @RestController
    public class OrderHystrixController {
    
        @Resource
        private PaymentHystrixService paymentHystrixService;
    
    
        @GetMapping("/consumer/payment/hystrix/ok/{id}")
        public String paymentOk(@PathVariable("id")Integer id) {
            String result = paymentHystrixService.paymentOk(id);
            return result;
        }
    
        @GetMapping("/consumer/payment/hystrix/timeout/{id}")
        public String paymentInfo_timeout(@PathVariable("id") Integer id) {
            String result = paymentHystrixService.paymentInfo_timeout(id);
            return result;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    5.6 正常测试

    启动80
    http://localhost/consumer/payment/hystrix/ok/1

    在这里插入图片描述
    http://localhost/consumer/payment/hystrix/tmeout/1
    在这里插入图片描述

    5.7 高并发测试

    启动JMeter对8001的压力测试,再通过80访问
    http://localhost/consumer/payment/hystrix/ok/1
    开始转圈圈了。狂点还可能报错。
    在这里插入图片描述

    服务端这么慢,用户不得骂你吗?我们来看看怎么解决。

    6 Hystrix的服务降级

    6.1 降级容错解决的维度要求

    在这里插入图片描述

    6.2 服务端的降级处理

    在8001的timeout接口新增@HystrixCommand注解,进行如下改造,设置兜底机制。

    
       /*
          通过@HystrixCommand来指定哪个方法由Hystrix来接管
             fallbackMethod属性: 指定哪个方法作为兜底方法
         */
        @HystrixCommand(fallbackMethod ="paymentInfo_TimeoutHandler", commandProperties = {
                //设置自身超时调用时间的峰值为 3 秒,峰值内可以正常运行,超过了需要有兜底的方法处理,服务降级fallback
                @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
        })
        public String paymentInfo_Timeout(Integer id) throws InterruptedException {
            int timeout = 3;
            // Hystrix底层调用的是Tomcat的线程池,我们在这里将线程名放回
            TimeUnit.SECONDS.sleep(timeout);
            return "线程:  "+Thread.currentThread().getName()+"  paymentInfo_OK, id = "+id + "\t" + "耗时"+ timeout +"s";
        }
    
        public String paymentInfo_TimeoutHandler(Integer id) {
            return "线程:  "+Thread.currentThread().getName()+"  paymentInfo_TimeoutHandler, id = "+id + "\t/(ㄒoㄒ)/~~";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    主启动类增加@EnableCircuitBreaker注解触发熔断功能
    在这里插入图片描述
    测试下,访问:http://localhost/consumer/payment/hystrix/timeout/1
    在这里插入图片描述
    可以注意到,此时处理的线程也变成了Hystrix...开头了。说明对于超时的情况使用了其它线程池的线程进行单独处理了。

    将接口的核心方法改造下。从超时的情况改造称为异常。

        @HystrixCommand(fallbackMethod ="paymentInfo_TimeoutHandler", commandProperties = {
                //设置自身超时调用时间的峰值为 3 秒,峰值内可以正常运行,超过了需要有兜底的方法处理,服务降级fallback
                @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
        })
        public String paymentInfo_Timeout(Integer id) throws InterruptedException {
            int timeout = 3;
            int temp = 3 / 0;
            // Hystrix底层调用的是Tomcat的线程池,我们在这里将线程名放回
    //        TimeUnit.SECONDS.sleep(timeout);
            return "线程:  "+Thread.currentThread().getName()+"  paymentInfo_OK, id = "+id + "\t" + "耗时"+ timeout +"s";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    再测试。
    在这里插入图片描述
    这说明对于异常或者超时的情况都将会使用兜底方案。

    6.3 客户端的降级处理

    之前我们说过,一般会将服务降级放在客户端,这是为了在上游及时发先问题,及时处理。现在就来实践下。

    在80的yml中添加。

    feign:
      hystrix:
        enabled: true  #老师说是要设置这个,我设置一个不管怎么范围都是超时
    
    • 1
    • 2
    • 3

    在主启动类添加@EnableHystrix注解。

    @SpringBootApplication
    @EnableFeignClients
    @EnableEurekaClient
    @EnableHystrix
    public class OrderHystrixMain80 {
        public static void main(String[] args) {
            SpringApplication.run(OrderHystrixMain80.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    改造80 controller中的paymentInfo_timeout接口。

       @GetMapping("/consumer/payment/hystrix/timeout/{id}")
        @HystrixCommand(fallbackMethod ="paymentInfo_TimeoutHandler", commandProperties = {
                //设置自身超时调用时间的峰值为 2 秒,峰值内可以正常运行,超过了需要有兜底的方法处理,服务降级fallback
                @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
        })
        public String paymentInfo_timeout(@PathVariable("id") Integer id) {
            String result = paymentHystrixService.paymentInfo_timeout(id);
            return result;
        }
    
        public String paymentInfo_TimeoutHandler(Integer id) {
            return "我是消费者80,对方系统繁忙,请稍后再试,/(ㄒoㄒ)/~~";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    测试。

    在测试之前记得将支付微服务8001的paymentInfo_timeout逻辑从异常改为sleep哟。
    在这里插入图片描述
    测试结果如下。
    在这里插入图片描述

    6.4 全局服务降级的配置

    上面的代码有如下问题。

    • 业务逻辑和异常处理被我们混在一块了,耦合度极高。
    • 每一个方法都需要有兜底方法

    解决方法,使用@DefaultProperties设置全局的fallback方法。
    在这里插入图片描述
    80的OrderHystrixController中添加全局fallback方法:

        //全局fallback方法,不能有传参
        public String payment_Global_FallbackMethod(){
            return "Global异常处理信息,请稍后再试!";
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    并在OrderHystrixController类上加上@DefaultProperties(defaultFallback = “payment_Global_FallbackMethod”),指定设置全局fallback方法。

    在这里插入图片描述
    将之前的@HystrixCommand注掉,稍微对方法进行下改动。重启微服务80.

        @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    //    @HystrixCommand(fallbackMethod ="paymentInfo_TimeoutHandler", commandProperties = {
    //            //设置自身超时调用时间的峰值为 2 秒,峰值内可以正常运行,超过了需要有兜底的方法处理,服务降级fallback
    //            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    //    })
        @HystrixCommand
        public String paymentInfo_timeout(@PathVariable("id") Integer id) {
            int var = 10/0;
            String result = paymentHystrixService.paymentInfo_timeout(id);
            return result;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    结果如下。
    在这里插入图片描述

    6.5 通配服务降级

    前面一节我们已经解决了代码膨胀的问题,接下来解决下代码耦合度过高的问题。

    在80的service包下新建PaymentFallbackService类,实现PaymentHystrixService接口

    public class PaymentFallbackService implements PaymentHystrixService{
        @Override
        public String paymentOk(Integer id) {
            return "------PaymentFallbackService  paymentOk /(ㄒoㄒ)/~~";
        }
    
        @Override
        public String paymentInfo_timeout(Integer id) {
            return "------PaymentFallbackService  paymentInfo_timeout /(ㄒoㄒ)/~~";
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    PaymentHystrixService中的@FeignClient注解增加fallback参数即可。
    在这里插入图片描述
    访问ok接口:http://localhost/consumer/payment/hystrix/ok/1,没有任何毛病
    在这里插入图片描述
    关闭8001服务,模拟服务器宕机。请读者自测。

    7 Hystrix的服务熔断

    7.1 熔断理论

    在这里插入图片描述
    前面介绍过服务熔断,这里再解释下,帮助读者理解。
    (1)调用正常方法失败会触发降级,而降级会触发fallback方法
    (2)但无论如何,降级一定是先调用正常方法,再调用fallback方法
    (3)假如单位时间降级次数过多,会触发熔断
    (4)熔断以后将会跳过正常方法直接调用fallback方法
    (5)所谓的熔断后服务不可用,就是因为跳过了正常方法,而直接执行了fallback方法

    7.2 服务熔断案例

    在8001的PaymentService中添加

     //====服务熔断
        @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
                @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),                      //开启断路器
                @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),         //请求总数阈值(默认20)
                @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),   //休眠时间窗口期(休眠多久进入半开模式(单位毫秒,默认5秒))
                @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),       //请求次数的错误率达到多少跳闸(百分率%,默认50%)
        })
        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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    对上面的参数解释如下。
    在这里插入图片描述

    HystrixCommandProperties.class可用看到所有可配置的参数。

    在8001的PaymentController中添加

    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id") Integer id){
        String result = paymentService.paymentCircuitBreaker(id);
        log.info("******result:" + result);
        return result;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    启动8001,执行测试。

    正数放行,http://localhost:8001/payment/circuit/1
    在这里插入图片描述
    负数,http://localhost:8001/payment/circuit/-1
    在这里插入图片描述
    借助Jmeter大量进行如上请求,使服务熔断,熔断10秒内就算是正确的请求也返回错误信息
    在这里插入图片描述
    10秒后进入半开模式,对请求进行处理,此时如果是正确的请求,那么就关闭熔断,否则再次进入熔断,10秒后再次开启半开模式,对请求进行处理,直到半开模式处理到正确请求。
    在这里插入图片描述

    7.3 熔断规则总结

    (1)熔断状态的变化

    下图总结了熔断的状态变化的规则
    在这里插入图片描述
    官网还给出了详细的流程图
    在这里插入图片描述
    (2)熔断开启的条件
    在这里插入图片描述
    在这里插入图片描述

    (3)断路器打开之后
    在这里插入图片描述

  • 相关阅读:
    sql 限制返回的行数、从表中随机返回n行数据、将NULL转换为实际值
    刷题记录(NC16884 食物链,NC51097 Parity game,NC235745 拆路)
    【Luogu】 P3206 [HNOI2010] 城市建设
    AUTOSAR C++14 编码指南(下)
    react native使用4-搭建安卓环境1
    ASP.NET Core 6框架揭秘实例演示[13]:日志的基本编程模式
    浮动优缺点及清除浮动的方法
    R语言代码示例
    常用 Shell 脚本
    超强AI绘图-文生图
  • 原文地址:https://blog.csdn.net/qq_41708993/article/details/126800638