• 十一、一文搞定spring cloud重要成员--Hystrix(断路器)


    由来

    在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。 为了解决这个问题,业界提出了断路器模型。

    是什么

    Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的,较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。

    具体使用

    依赖

    <!--断路器依赖-->
     <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</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-netflix-hystrix-dashboard</artifactId>
     </dependency>

    在restTemplate+ribbon方式下

    1. 改造service

      在方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法

      @Service
       public class HelloService {
       ​
           @Resource
           RestTemplate restTemplate;
       ​
           @HystrixCommand(fallbackMethod = "error")
           public String helloService(){
               return restTemplate.getForObject("http://user-service/hello",String.class);
           }
       ​
           public String error(){
               return "error";
           }
       ​
       }
    2. 开启熔断:启动类

      @SpringBootApplication
       @EnableEurekaClient //标识Eureka客户端
       @EnableHystrix  //开启断路器
       @EnableHystrixDashboard //开启断路器仪表盘
       public class ConsumerRibboApplication {
       ​
          public static void main(String[] args) {
             SpringApplication.run(ConsumerRibboApplication.class, args);
          }
       ​
          //向程序的ioc注入一个bean: restTemplate;并通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。
          @Bean
          @LoadBalanced
          RestTemplate restTemplate() {
             return new RestTemplate();
          }
       ​
          //加入断路器仪表盘,注入bean
          @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;
          }
       }
    3. 查看仪表盘

      http://localhost:8002/hystrix

       

      输入URL:http://localhost:8002/actuator/hystrix.stream

       

    4. 设置超时时间(默认1s)

      可以使用设置commandProperties属性来设置:execution.isolation.thread.timeoutInMilliseconds

      @HystrixCommand(fallbackMethod = "error",
               commandProperties = {
                   @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "500")
               })
       public String helloService(){
           return restTemplate.getForObject("http://user-service/hello",String.class);
       }

      关闭超时设置:execution.timeout.enabled设为false

       @HystrixCommand(fallbackMethod = "error",
               commandProperties = {
                   @HystrixProperty(name = "execution.timeout.enabled", value = "false")
               })
       public String helloService(){
           return restTemplate.getForObject("http://user-service/hello",String.class);
       }

      其它值得关注的属性

      circuitBreaker.requestVolumeThreshold:在给定的时间范围内,方法应该被调用的次数

      circuitBreaker.errorThresholdPercentage:在给定的时间范围内,方法调用产生失败的百分比

      metrics.rollingStats.timeInMilliseconds:控制请求量和错误百分比的滚动时间周期

      circuitBreaker.sleepWindowInMilliseconds:处于打开状态的断路器要经过多长时间才会进入到半开状态,进入半开状态之后,将会再次尝试失败的原始方法。

    在feign方式下

    1. 添加配置开启断路器

       feign:
         hystrix:
           enabled: true #开启断路器
    2. 创建熔断处理类,实现对应接口

       @Component
       public class ErrorHander implements HelloAction {
           @Override
           public String hello() {
               return "feign error";
           }
       }
    3. 接口指定熔断处理类,fallback

    @FeignClient(value = "user-service",fallback = ErrorHander.class)
     public interface HelloAction {
     ​
         @RequestMapping(value = "/hello",method = RequestMethod.GET)
         String hello();
     ​
     }

    4.设置超时时间

     #hystrix断路参数配置
     hystrix:
       command:
         default: #default时为默认配置, 相关参数说明在 HystrixCommandProperties
           execution:
             isolation:
               thread:
                 timeoutInMilliseconds: 60000

    聚合多个Hystrix流

    使用的是Netfilx的另外一个项目Turbine

    依赖引入

     <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
     </dependency>

    启动类开启

    @EnableTurbine

    添加配置

     turbine:
         app-config: service-1,service-2  #需要注册的服务
         cluster-name-expression: "'default'" #default表示收集集群中的所有聚合流

    源码地址:https://github.com/kinglead2012/myblog

  • 相关阅读:
    详细聊聊k8s deployment的滚动更新(一)
    更新k8s镜像版本的三种方式
    深入理解docker信号机制以及dumb-init的使用
    10分钟教你理解反射
    nodejs的交互式解释器模式常用命令
    nrm的安装和使用
    复杂sql语句之单字段分类count计数和多字段count计数
    navicat连接mysql出现2059
    mongodb常规操作语句
    System.Web.NullPointerException
  • 原文地址:https://www.cnblogs.com/kinglead/p/14037600.html
Copyright © 2020-2023  润新知