熔断器Hystrix

作者: 董二弯 | 来源:发表于2019-05-12 15:21 被阅读15次

    微服务中服务之间的相互依赖性错综复杂,一个网络请求通常需要调用多个服务实例才能完成。如果一个服务不可用,如网络延迟或故障,会影响依赖于这个服务的其它服务,最后导致整个系统处于瘫痪的状态。为解决这种雪崩效应,引进熔断组件Hystrix,当出现故障后会自动剔除服务实列。Hystrix除了一些基本的熔断器,还能实现服务降级、服务限流的功能,并提供了界面展示健康状态的功能。本章讲诉如何使用RestTemplate和Feign消费服务是使用Hystrix,并介绍Hystrix的工作原理。

    Hystrix的设计原则

    • 防止单个服务的故障耗尽整个服务的Servlet容器(如Tomcat)的线程池资源。
    • 快速失败机制,如果某个服务出现了故障,则调用该服务的请求快速失败,而不是线程等待。
    • 提供回退方案,在请求发生故障时,提供设定好的回退方案。
    • 使用熔断器机制,防止故障扩散到其他的服务。
    • 提供熔断器的监控组件Hystrix Dashboard,可以实时监控熔断器的状态。

    Hystrix的工作机制

    当服务的某个API接口的失败次数在一定时间内小于设定的阈值时,熔断器处于关闭状态,该API接口正常提供服务。当该API接口处理请求的失败次数大于设定的阈值时,Hystrix判定该API接口出现了故障,打开熔断器,这时该API接口会执行快速失败的逻辑,不执行业务逻辑,请求的线程不会处于阻塞状态。处于打开状态的熔断器在一定时间后会处于半打开状态,并将一定数量的请求执行正常逻辑,剩余的请求会执行快速失败。若执行正常逻辑的请求失败了,则熔断器继续打开,若成功了,则熔断器关闭。这样熔断器就具有了自我修复的功能。

    在RestTemplate上使用熔断器

    本章案例在前面章节的案例基础之上进行改造。在讲述ribbon章节时,eureka-ribbon-client工程中我们使用RestTemplate调用了eureka-client的“/hi”接口,并用Ribbon做了负载均衡,现在在此基础上加Hystrix熔断器的功能。

    • 添加Hystrix的起步依赖
    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
    
    • 在启动类上添加@EnableHystrix注解开启Hystrix的熔断器功能。
    @SpringBootApplication
    @EnableEurekaClient
    @EnableHystrix
    @EnableHystrixDashboard
    public class EurekaRibbonClientApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaRibbonClientApplication.class, args);
        }
    }
    
    • 修该RibbonService的代码,在方法中加上@HystrixCommand注解。有了@HystrixCommand方法就用Hystrix熔断器的功能,其中,fallbackMethod为处理回退逻辑的方法,在本例中,直接返回了一个字符串。在熔断器打开的状态下,会执行回退逻辑。回退逻辑最好是返回一些静态的字符串,不需要处理复杂的逻辑,也不需要远程调用其它的服务,这样能执行快速失败,释放线程资源。如果在回退逻辑中一定要调用远程服务,最好在远程调度其它的服务时,也加上熔断器。
    public class RibbonServiceHystrix {
        @Autowired
        private RestTemplate restTemplate;
    
        @HystrixCommand(fallbackMethod = "hiError")
        public String hiFromClient() {
            return restTemplate.getForObject("http://eureka-client/hi?name=dzy", String.class);
        }
        public String hiError(){
            return "error";
        }
    }
    
    • 启动eureka-server和eureka-ribbon-client。此时没有启动eureka-client,所以eureka-ribbon-client肯定是访问不通eureka-client接口的。此时访问http://localhost:8765/hi,浏览器会显示回退逻辑返回的错误字符串。做到了快速失败,线程不在阻塞。

    在Feign上使用熔断器

    • 之前介绍Feign提到本身已经集成了熔断器的功能,Feign的起步依赖已经引入了Hystrix的依赖,所以不需要在pom文件中添加Hystrix的依赖。只需要在配置文件中开启Hystrix功能即可。
    feign:
      hystrix:
        enabled: true
    
    • 在声明式接口中的@FeignClient注解上添加fallback属性来配置快速失败的处理类。该处理类作为Feign熔断器的逻辑处理类,必须实现被@FeignClient修饰的接口,最后需要以Spring Bean的形式注入IoC容器中。
    @FeignClient(value = "eureka-client", configuration = FeignClientConfig.class,fallback = HiFailBack.class)
    public interface HiFeignClient {
        @GetMapping("/hi")
        String hi(@RequestParam(value = "name") String name);
    }
    
    @Component
    public class HiFailBack implements HiFeignClient {
    
        @Override
        public String hi(String name) {
            return "hystrix error";
        }
    }
    
    • 启动eureka-server,eureka-feign-client,此时没有启动eureka-client,所以eureka-feign-client接口调用eureka-client的接口是肯定连接不通的。在浏览器访问eureka-feign-client接口,浏览器会出现配置的错误字符串,说明实现了快速失败。

    使用Hystrix Dashboard监控熔断器的状态

    Hystrix Dashboard 是监控Hystrix的熔断状况的一个组件,提供了数据监控和友好的图形化展示界面。

    在RestTemplate中使用Hystrix Dashboard

    在eureka-ribbon-client的基础上改造。

    • 在pom文件中加上Actuator的起步依赖,Hystrix Dashboard的起步依赖。
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    </dependency>
    
    • 在启动类上加上@EnableHystrixDashboard开启Hystrix Dashboard的功能。
    @SpringBootApplication
    @EnableEurekaClient
    @EnableHystrix
    @EnableHystrixDashboard
    public class EurekaRibbonClientApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaRibbonClientApplication.class, args);
        }
    }
    
    • 依此启动eureka-server,eureka-client和eureka-ribbon-client(我的端口为8765),确定两个eureka client已经注册到了eureka server中。
      在浏览器访问http://localhost:8765/hystrix,会出现Hystrix Dashboard的界面。
      image.png
      在界面中依此填写http://localhost:8765/hystrix.stream,200,forezp(任意填写),点击“monitor”,进入界面
      image.png
      监控图中用圆点来表示服务的健康状态,健康度从100%-0%分别会用绿色、黄色、橙色、红色来表示。 另外,这个圆点也会随着流量的增多而变大。 监控图中会用曲线(圆点旁边)来表示服务的流量情况,通过这个曲线可以观察单个接口的流量变化/趋势。对应的指标含义如下
      image.png

    在feign中使用Hystrix Dashboard

    • 添加Actuator,Hystrix,Hystrix Dashboard的起步依赖。这里需要注意,既然Feign自带Hystrix,那为什么还需要引入spring-cloud-starter-hystrix?这是因为Feign自带的是Hystrix的依赖不是Hystrix起步依赖。
     <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    </dependency>
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    • 在启动类上加上@EnableHystrixDashboard开启Hystrix Dashboard的功能。
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients
    @EnableHystrixDashboard
    @EnableHystrix
    public class EurekaFeignClientApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaFeignClientApplication.class, args);
        }
    }
    

    只需要上述两步就可以在Feign中开启Hystrix Dashboard的功能。

    使用Turbine聚合监控

    在使用Hystrix Dashboard组件监控服务的熔断状况时,每个服务都有一个Hystrix Dashboard主页,当服务数量很多时,监控非常不方便。为了同时监控多个服务的熔断器的状况,Netflix开源了Hystrix另一个组件Turbine。Turbine用于聚合多个Hystrix Dashboard,将多个Hystrix Dashboard组件的数据放在一个页面上展示,进行集中监控。

    • 新建一个Module工程,取名为turbine-server,在pom中添加turbine,actuator,test的起步依赖。
     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
    </dependency>
    
    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-turbine</artifactId>
    </dependency>
     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
     </dependency>
    
    • 在配置文件application加上相关的配置。
    server:
      port: 8770
    spring:
      application:
        name: turbine-server
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
    management:
      security:
        enabled: false
    turbine:
      app-config: eureka-ribbon-client,eureka-feign-client
      cluster-name-expression: new String("default")
      aggregator:
        clusterConfig: default
    

    其中turbine.app-config配置了需要监控的服务名,turbine.cluster-name-expression默认为服务器的集群,此时用默认的即可。turbine.aggregator.clusterConfig可以不写,因为默认就是default。

    • 启动类上添加@EnableTurbine注解,启动Turbine功能
    @SpringBootApplication
    @EnableEurekaClient
    @EnableTurbine
    public class TurbineServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(TurbineServerApplication.class, args);
        }
    
    }
    
    
    • 启动eureka-server,eureka-ribbon-client,eureka-feign-client,turbine-server
      在浏览器访问http://localhost:8765/hystrix,在这个界面为eureka-ribbon-client的
      Hystrix Dashboard界面(用其它服务的Hystrix Dashboard也可,只要监控流为turbine服务器地址就行,但在项目中只会启用一个服务的Hystrix Dashboard),在界面中依此输入监控流的Url地址http://localhost:8770/turbine.stream,监控时间间隔为2000毫秒和title,点击“monitor”,可以看到如下界面。
      image.png
      可以看到这个界面同时聚合了eureka-ribbon-client和eureka-feign-client的Hystrix Dashboard。

    总结

    在这一章学习了熔断器Hystrix,其中包括什么是Hystrix,Hystrix的工作原理,TestTemplate、Feign结合Hystrix的使用。最后介绍使用图形化监控组件Hystrix Dashboard,以及监控聚合组件Turbine。在下一章中介绍路由网关Zuul。

    PS:项目github地址:https://github.com/dzydzydzy/spring-cloud-example.git

    相关文章

      网友评论

        本文标题:熔断器Hystrix

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