• Hystirx熔断降级机制


    Hystrix特性

    • 服务降级(服务提供者端):返回托底数据,避免服务雪崩
    • 熔断:当服务的失败率达到阈值时,断路器打开,自动走降级方法
    • 隔离(限流):提供独立的线程池处理微服务的调用,与本地请求的线程池隔离,同时支持线程池限流

    使用Hystrix

    引入依赖

            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-netflix-hystrixartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4

    启动类上添加注解

    @EnableHystrix
    
    • 1

    使用Hystrix保护接口,在接口方法上添加注解 @HystrixCommand(fallbackMethod = “fallback”),其中fallback是当接口调用发生异常时,执行的降级方法。如下两种情况都会触发降级。

    • 运行时异常
    • 超时
    @SpringBootApplication
    @RestController
    @EnableHystrix // 启动类上要添加注解
    public class Micro4App {
    
        public static void main(String[] args) {
            SpringApplication.run(Micro4App.class);
        }
    
        @HystrixCommand(fallbackMethod = "fallback")
        @GetMapping("/test1")
        public String test1() throws InterruptedException {
    //        int i = 1/0;
            TimeUnit.SECONDS.sleep(3);
            return "Micro4App test1";
        }
    
        public String fallback(){
            return "fallback : Micro4App test1 方法故障了";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    配置Hystrix的超时时间

    全局配置 默认不设置是1秒

    # 方法调用超过5秒则触发降级
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 5000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在某个具体的接口上,通过@HystrixCommand配置

        @HystrixCommand(fallbackMethod = "fallback",commandProperties = {
                @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
        })
        @GetMapping("/test1")
        public String test1() throws InterruptedException {
    //        int i = 1/0;
            TimeUnit.SECONDS.sleep(3);
            return "Micro4App test1";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    断路器

    马丁福勒断路器论文:https://martinfowler.com/bliki/CircuitBreaker.html

    在调用指定服务时,如果说这个服务的失败率达到你输入的一个阈值,将断路器从closed状态,转变为open状态,指定服务是无法被访问的,如果你访问就直接走fallback方法,在一定的时间内,open状态会再次转变为half open状态,允许一个请求发送到我的指定服务,如果成功,转变为closed,如果失败,服务再次转变为open状态,会再次循环到half open,直到断路器回到一个closed状态。

    在这里插入图片描述

    配置断路器的监控界面

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboardartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    启动类中加注解

    @EnableHystrixDashboard
    
    • 1

    开启Hystirx的监控Servlet,用于提供监控数据

    @WebServlet("/hystrix.stream")
    public class HystrixServlet extends HystrixMetricsStreamServlet {
    }
    
    //------------------------------------------------------------
    // 在启动类上,添加扫描Servlet的注解
    @ServletComponentScan("com.qf.servlet")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    配置文件中设置允许监控localhost

    hystrix:
      dashboard:
        proxy-stream-allow-list: localhost
    
    • 1
    • 2
    • 3

    测试直接访问http://host:port/hystrix 他只监控加了 降级的 方法

    在这里插入图片描述

    在这里插入图片描述
    断路器的属性(默认10s秒中之内至少有20个请求,50%的请求出现异常或超时,断路器开。)

    配置信息namevalue
    断路器的开关circuitBreaker.enabledtrue
    至少有20个请求才进行errorThresholdPercentage错误百分比计算circuitBreaker.requestVolumeThreshold20
    请求总数失败率达到%多少时circuitBreaker.errorThresholdPercentage50
    断路器open状态后,多少秒是拒绝请求的circuitBreaker.sleepWindowInMilliseconds5000
    强制让服务拒绝请求circuitBreaker.forceOpenfalse
    强制让服务接收请求circuitBreaker.forceClosedfalse
        @GetMapping("/test2/{flag}")
        @HystrixCommand(fallbackMethod = "test2fallback",commandProperties = {
                @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
                @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
                @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "70"),
                @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000")
        })
        public String test2(@PathVariable("flag") String flag) throws InterruptedException {
    
            System.out.println("进入test2 方法了。。。。");
            if (flag.equals("1")){
                int i = 1/0;
            }
            System.out.println(Thread.currentThread().getName());
            return "test2 ok";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
     //fallbackMethod 中设置的是降级方法的名字
        @GetMapping("/test1")
        @HystrixCommand(fallbackMethod = "test1fallback",commandProperties = {
              //设置该接口的超时时间,一旦超时返回降级方法中的结果
                @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
        })//加了这个注解超时时间不超过1秒,超过就降级
        public String test1() throws InterruptedException {
            System.out.println("test还没熔断");
            int a=1/0;
    
    //        Thread.sleep(3000);
           return "hello hystrix";
        }
    
    
    
        public String test1fallback() throws InterruptedException{
            System.out.println("-------------");
            return "test1()降级方法返回的数据";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    限流(隔离)

    Hystrix通过线程池配置可以进行请求限流。

    • 可以指定请求运行线程池(独立于tomcat的线程池)
    • 可以指定线程池的线程数量和等待队列大小
    • 当请求并发数量超过线程数量+队列大小后,请求进入降级方法
        @GetMapping("/test3")
        @HystrixCommand(
                fallbackMethod = "fallback",
                commandProperties = {
                        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
                },
                threadPoolKey = "mypool",
                threadPoolProperties = {
                        @HystrixProperty(name = "coreSize", value = "5"),
                        @HystrixProperty(name = "maxQueueSize", value = "5")
                }
        )
        public String test3() throws InterruptedException {
            System.out.println(Thread.currentThread().getName());
            TimeUnit.SECONDS.sleep(1);
            return "test3 ok";
        }
    
        @GetMapping("/tt/{num}")
        public String tt(@PathVariable("num") Integer num) throws InterruptedException {
            RestTemplate restTemplate = new RestTemplate();
    
            CountDownLatch countDownLatch = new CountDownLatch(num);
    
            for (int i=0;i<num;i++){
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String s = restTemplate.getForObject("http://localhost:9300/test3", String.class);
                        System.out.println(Thread.currentThread().getName()+s);
                        countDownLatch.countDown();
                    }
                }).start();
            }
    
            countDownLatch.await();
            return "ok";
    
        }
    
    • 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

    自己: 限流超出的请求不会 开启 断路器 ,不记录失败数!

     @GetMapping("/test2")
        public String test2(){
            System.out.println("处理请求的线程名字为"+Thread.currentThread().getName());
            return Thread.currentThread().getName();
        }
    
    
        @GetMapping("/test3")
        /**
         * 限制 test3的最大并发度为10 ,即最多可以同时处理10个请求,
         * 超出的请求会被降级
         * @return
         */
        @HystrixCommand(fallbackMethod = "test3fallback",
        threadPoolKey = "mypool",
                threadPoolProperties = {
                        @HystrixProperty(name = "coreSize", value = "5"),
                        @HystrixProperty(name = "maxQueueSize", value = "5")
                }
        )
        public String test3(){
            System.out.println("处理请求的线程名字为"+Thread.currentThread().getName());
            return Thread.currentThread().getName();
        }
    
        public String test3fallback(){
            return "这是test3的降级方法";
        }
    
    }
    
    
    • 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
  • 相关阅读:
    好用的编辑器Typora分享
    Linux下载安装 RabbitMQ​
    基于JAVA计算机类课程实验平台计算机毕业设计源码+系统+mysql数据库+lw文档+部署
    设置服务账号Service Accounts(sa)的token不挂载到pod
    数学工程学|正态分布及其图形
    c++初阶—类和对象(下)
    大数据面试题——spark
    C语言中的常量、变量及关键字
    【css揭秘】- 47个不可不知的 css 技巧(上篇0-19)
    传感器的基本特性
  • 原文地址:https://blog.csdn.net/qq_53374893/article/details/132911112