• Hystrix学习笔记


    Hystrix学习总结

    雪崩效应

    在微服务应用中,一个请求可能会调用多个微服务,从而形成复杂的调用链路;而当链路中的某一个微服务出现问题时(服务调用响应时间过长或者服务不可用),调用这个服务的请求也会被阻塞,对这个服务的调用会占用越来越多的系统资源,进而引起系统崩溃,这句是所谓的雪崩效应。

    解决方法

    解决雪崩效应主要有3种方法:

    服务熔断

    当扇出链路的某个微服务不可用或者响应时间过长时,暂时切断对这个微服务的调用,进行服务降级,返回错误信息;等到这个服务可以被正常调用时,恢复对它的调用。

    服务熔断的核心在于切断对服务的调用,另外服务熔断和降级一般是同时使用的,Hystrix就是同时使用的。

    服务降级

    服务降级是当服务出问题或者影响到核⼼流程的性能时,暂时将服务屏蔽掉,待⾼峰或者问题解决后再打开。

    服务降级一般是当某个服务熔断之后,此服务将不再被调用,我们可以准备⼀个本地的fallback回调,返回⼀个缺省值;虽然服务水平降低了,但是还是可用的。

    服务限流

    服务降级是通过暂时关掉服务来解决问题的,但是有些核心服务不能这样做,不能直接关掉;此时可以通过限流来解决,在流量高峰期限制一次最多能处理的请求,从而避免流量太多,服务无法处理这么多请求直接挂掉。

    Hystrix

    Hystrix介绍

    Netflix开源的一个组件库,可以防止微服务调用中出现的级联错误,提供微服务系统的可用性。

    Hystrix使用

    1、引入Hystrix的依赖

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
                <version>2.1.0.RELEASE</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、启动类上添加@EnableCircuitBreaker注解

    @EnableCircuitBreaker //开启熔断器
    
    • 1

    3、定义服务降级处理方法,并把业务方法和服务降级方法关联起来

        /**
         * 提供者模拟处理超时,调用方法添加Hystrix控制
         * 适用@HystrixCommand注解进行熔断控制
         * @param userId
         * @return
         */
        @HystrixCommand(threadPoolKey = "findResumeOpenStateTimeout",  //线程池唯一标识,要保持唯一
                threadPoolProperties = {   //线程池细节属性配置
                @HystrixProperty(name = "coreSize", value = "1"), //线程数
                @HystrixProperty(name = "maxQueueSize", value = "20"),  //等待队列长度
        }, commandProperties = {    //每一个属性都是HystrixProperty
                @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")},
                fallbackMethod = "myFallBack"  //降级方法
                )
        @GetMapping("/checkStateTimeout/{userId}")
        public Integer findResumeOpenStateTimeout(@PathVariable Long userId) {
            //使用了ribbon负载均衡,直接调用即可
            String url = "http://lagou-service-resume/resume/openState" + userId;
            Integer forObject = restTemplate.getForObject(url, Integer.class);
            return forObject;
        }
    
        /**
         * 定义降级方法,返回预设默认值,该方法的形参和返回值需要和原始方法保持一致
         *
         * @return
         */
        public Integer myFallBack(Long userId) {
            //兜底数据
           return -123333;
        }
    
    • 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

    舱壁模式

    默认情况下Hystrix有一个线程池,里面有10个线程,为所有添加了@HystrixCommand注解的方法提供线程,如果这些方法接收的请求超过了10个,其它请求就只能等待或者拒绝连接。

    如果不进行其它设置,10个线程很快就会被用完,那么其它请求就只能等待或者拒绝了,为了解决这个问题,Hystrix采用的解决方法是为每一个控制方法创建一个线程池,这被称为舱壁模式。

    设置如下,threadPoolKey必须唯一,不然就是共用一个线程池了,coreSize和maxQueueSize则是设置了线程池线程数和线程池等待队列长度。

       @HystrixCommand(threadPoolKey = "findResumeOpenStateTimeout",  //线程池唯一标识,要保持唯一
                threadPoolProperties = {   //线程池细节属性配置
                @HystrixProperty(name = "coreSize", value = "1"), //线程数
                @HystrixProperty(name = "maxQueueSize", value = "20"),  //等待队列长度
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    工作流程

    跳闸、自我修复机制

    前面已经提到了Hystrix是一个断路器,可用用来进行服务熔断,那么什么时候才会熔断呢?

    Hystrix的工作流程如下图所示:
    在这里插入图片描述

    1. 当调用出现问题的时候,Hystrix会开启一个时间窗,默认为10s
    2. Hystrix会统计在这个时间窗内是否达到了最小请求数,如果没有达到,会重置统计信息,等调用再次出现问题,重新开始统计;
    3. 如果达到了最小请求数,就统计失败的请求数在所有请求数中的占比是否达到阈值,如果没有达到,同样也会重置统计信息,回到第一步;
    4. 如果达到阈值,就会跳闸,然后开启一个活动窗口,默认是5s,每隔5s,Hystrix会让一个请求通过,到达那个问题服务,看是否调用成功,如果成功,整个流程回到第一步,如果没有成功,流程回到第3步;

    上面提到的窗口时间是可以在@HystrixCommand注解的commandProperties中进行配置的

                commandProperties = {  //熔断细节配置,每个属性都是一个HystrixProperty
                        //统计时间窗口定义
                        @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "20000"),
                        //统计时间窗口内的最小请求数
                        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "8000"),
                        //统计时间窗口内的错误数量百分比阈值
                        @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "2"),
                        //自我修复时的活动窗口长度
                        @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "3000")
                },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    上面的配置也可以在yml文件中进行配置

    hystrix:
      command:
        default:
          circuitBreaker:
            #强制打开熔断器,设置为true,强制断路器进入打开状态,将会拒绝所有请求,默认为false
            forceOpen: false
            # 触发熔断错误⽐例阈值,默认值50%
            errorThresholdPercentage: 50
            # 熔断后休眠时⻓,默认值5秒
            sleepWindowInMilliseconds: 3000
            # 熔断触发最⼩请求次数,默认值是20
            requestVolumeThreshold: 2
          execution:
            isolation:
              thread:
              # 熔断超时设置,默认为1秒
              timeoutInMilliseconds: 2000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    断路监控

    Hystrix正常工作时会显示UP状态,跳闸后会显示为CIRCUIT_OPEN状态;通过SpringBoot提供的健康检查可以观察Hystrix跳闸的状态,首先需要开启配置,当然也需要引入actuator的依赖

    # springboot中暴露健康检查等断点接⼝
    management:
      endpoints:
        web:
          exposure:
            include: "*"
      # 暴露健康接⼝的细节
      endpoint:
        health:
          show-details: always
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    等启动后,在浏览器输入http://localhost:8090/actuator/health就可以看到状态了(前面的地址需要改为你自己的地址),接口返回的数据如下图,可以看到此时是正常工作的状态。
    在这里插入图片描述

    上面我们通过SpringBoot提供的监控检查功能可以看到Hystrix的工作状态,但是都是通过请求接口返回数据来看的,略有麻烦,实际上还可以通过Hystrix Dashboard来观察Hystrix的状态。

    1、引入Hystrix dashboard依赖

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
                <version>2.1.0.RELEASE</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、启动类添加注解@EnableHystrixDashboard注解,激活仪表盘

    @EnableHystrixDashboard //激活仪表盘
    
    • 1

    3、注册监控Servlet

        /**
         * 监控Servlet,监控数据来自于这个微服务
         * @return
         */
        @Bean
        public ServletRegistrationBean getServlet() {
            HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
            ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
            registrationBean.setLoadOnStartup(1);
            registrationBean.addUrlMappings("/actuator/hystrix.stream");
            registrationBean.setName("HystrixMetricsStreamServlet");
            return registrationBean;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4、
    在这里插入图片描述
    输入监控的微服务断点地址http://localhost:8090/actuator/hystrix.stream,即可看到Hystrix的详细信息。

    聚合监控

    参考资料

    1. 《某训练营课程》
  • 相关阅读:
    Linux centos7配置JDK环境
    消息队列 记录
    Python 学习之路
    ClickHouse 挺快,esProc SPL 更快
    私有继承和虚函数私有化能用么?
    Firewalld防火墙
    Python用于解析 XML 数据之untangle使用详解
    Java项目:SSM医药信息管理系统
    【django】Forbidden (CSRF cookie not set.)
    考pmp有用么?
  • 原文地址:https://blog.csdn.net/wsb_2526/article/details/126803013