美文网首页
SpringCloud Netflix Hystrix熔断容错降

SpringCloud Netflix Hystrix熔断容错降

作者: kaixingdeshui | 来源:发表于2020-11-12 11:15 被阅读0次

    SpringCloud Netflix Hystrix熔断容错降级

    现象
    在微服务中,一个请求有可能是多个微服务协同处理,请求一旦大量被阻塞,会占用大量资源,有可能会使整个系统雪崩。
    为了防止出现这种现象,需要一种机制来处理请求堆积情况,出现了Hystrix。
    Hystrix的构建思路:
    1.服务限流:服务消费者限制自身对某一服务能够发起的并发请求数量,超过数量则不调用
    2.服务熔断:熔断状态下,服务消费者不会发起对某一服务的调用
    3.服务降级:请求异常的情况下,程序执行指定的降级策略

    官方文档介绍:
    https://www.springcloud.cc/spring-cloud-netflix.html

    image.png
    Hystrix 集成

    1.pom导入依赖

    <!--hystrix 熔断容错-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    

    实现方式一:
    继承HystrixCommand,重写run,getFallback方法:

    /**
     * hystrix 熔断容错机制
     */
    public class CustomerCommand extends HystrixCommand<Object> {
    
        private RestTemplate restTemplate;
    
        public CustomerCommand(RestTemplate restTemplate) {
    //        super(setter);
            super(//也可以在配置文件里配置信息
                    Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("study-hystrix"))
                            .andCommandKey(HystrixCommandKey.Factory.asKey("CustomerController"))
                            //定义线程池
                            .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("studyThreadPool"))
                    .andCommandPropertiesDefaults(
                            HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(100)//执行超时时间100ms
                            .withCircuitBreakerSleepWindowInMilliseconds(5000))//熔断时间5s
                    .andThreadPoolPropertiesDefaults(
                            HystrixThreadPoolProperties.Setter().withCoreSize(1).withMaxQueueSize(1))
    
            );
            this.restTemplate = restTemplate;
        }
    
        @Override
        protected Object run() throws Exception {
            System.out.println("当前线程:"+Thread.currentThread().getName());
            //核心实现,调用方法
            Object result = restTemplate.getForObject("http://hello-server/client_1",String.class,"");
            return result;
        }
    
        @Override
        protected Object getFallback() {
            System.out.println("降级处理");
            return "返回降级结果";
        }
    
    }
    

    在controller里直接创建调用:

    @RestController
    public class CustomerController {
    
      @Autowired
      private RestTemplate restTemplate;
    
      /**
       *第一种方式实现降级:通过继承HystrixCommand,重写run,getFallback方法
       * @return
       */
      @GetMapping("/test")
      public Object test(){//超时降级处理
          return new CustomerCommand(restTemplate).execute();
      }
    }
    

    application配置信息

    server:
      port: 8003
    
    spring:
      application:
        name: hystrix-demo
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    

    第二种方式:
    通过注解的方式

    @RestController
    public class CustomerController {
        @Autowired
        private RestTemplate restTemplate;
        /**
         * 第二种方式实现降级:用注解的方式
         * 需要在application入口加
         * //熔断注解
         * @EnableCircuitBreaker
         *fallbackMethod :定义降级执行的方法名
         * @return
         */
        @GetMapping("/test2")
        @HystrixCommand(fallbackMethod = "callTimeOutFallBack",
                threadPoolProperties =
                {@HystrixProperty(name = "coreSize",value = "1"),
                @HystrixProperty(name = "queueSizeRejectionThreshold",value = "1")},
                commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "100")})
        public Object getTest2(){//超时降级处理
            return restTemplate.getForObject("http://hello-server/client_1",String.class,"");
        }
    
        public Object callTimeOutFallBack(){
            return "请求test2 降级";
        }
    
    }
    

    在程序入口加上EnableCircuitBreaker注解

    @SpringBootApplication
    @EnableEurekaClient
    //熔断注解
    @EnableCircuitBreaker
    public class LearnHystrixApplication {
    
       public static void main(String[] args) {
           SpringApplication.run(LearnHystrixApplication.class, args);
       }
    }
    

    Hystrix资源隔离

    不管是注解还是继承HystrixCommand,都是在线程池里执行,确保资源隔离。


    image.png

    初始化过程

    HystrixCommand 的父类 AbstractCommand 构造方法做初始化:


    image.png
    //命令分组名称(服务名)
    this.commandGroup = initGroupKey(group);
    //命令名称(接口/业务)
    this.commandKey = initCommandKey(key, getClass());
    //加载配置
    this.properties = initCommandProperties(this.commandKey, propertiesStrategy, commandPropertiesDefaults);
    this.threadPoolKey = initThreadPoolKey(threadPoolKey, 
    this.commandGroup, this.properties.executionIsolationThreadPoolKeyOverride().get());
    //度量器。收集命令执行的数据收集和统计
    this.metrics = initMetrics(metrics, this.commandGroup, 
    this.threadPoolKey, this.commandKey, this.properties);
    //熔断器
    this.circuitBreaker = initCircuitBreaker(this.properties.circuitBreakerEnabled().get(), circuitBreaker, this.commandGroup, this.commandKey, this.properties, this.metrics);
    //线程池,资源隔离
    this.threadPool = initThreadPool(threadPool, this.threadPoolKey, threadPoolPropertiesDefaults);
    

    执行流程

    HystrixCommand.execute()返回一个Future对象:

    image.png

    通过Observable 观察者模式实现发布订阅消费事件


    image.png

    terminateCommandCleanup
    unsubscribeCommandCleanup
    applyHystrixSemantics


    image.png

    度量计数


    image.png
    线程池执行applyHystrixSemantics--> executeCommandAndObserve->
    executeCommandWithSpecifiedIsolation->threadPool.getScheduler
    image.png

    Hystrix 可视化监控

    1. pom导入依赖
    <!--web-->
     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    <!--可监视化-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            </dependency>
    

    2.添加注解

    /**
     * 可视化网页
     * http://localhost:9999/hystrix
     */
    @SpringBootApplication
    //启用hystrix 可视化
    @EnableHystrixDashboard
    public class LearnDashboardApplication {
        public static void main(String[] args) {
            SpringApplication.run(LearnDashboardApplication.class, args);
        }
    }
    

    3.application配置

    server:
      port: 9999
    
    spring:
      application:
        name: dashboard-demo
    
    hystrix:
      dashboard:
        proxy-stream-allow-list: "*"
    
    image.png

    在需要开放监控的项目中配置监控端点:

    #dashboard端点监控
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    image.png

    相关文章

      网友评论

          本文标题:SpringCloud Netflix Hystrix熔断容错降

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