六、Hystrix断路器

一、概述

1、Hystrix是什么

Hystrix是一个用于处理分布式系统的 延迟容错 的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下, 不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常, 这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

2、分布式系统面临的问题

复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。下图中的请求需要调用A,P,H,I四个服务,如果一切顺利则没有什么问题,关键是如果I服务超时就会出现服务雪崩。

在这里插入图片描述

3、服务雪崩

多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。

4、对于服务依赖的保护的3种解决方案

1、熔断模式:这种模式主要是参考电路熔断,如果一条线路电压过高,保险丝会熔断,防止火灾。放到我们的系统中,如果某个目标服务调用慢或者有大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。
2、隔离模式:这种模式就像对系统请求按类型划分成一个个小岛的一样,当某个小岛被火少光了,不会影响到其他的小岛。例如可以对不同类型的请求使用线程池来资源隔离,每种类型的请求互不影响,如果一种类型的请求线程资源耗尽,则对后续的该类型请求直接返回,不再调用后续资源。这种模式使用场景非常多,例如将一个服务拆开,对于重要的服务使用单独服务器来部署,再或者公司最近推广的多中心。
3、限流模式:上述的熔断模式和隔离模式都属于出错后的容错处理机制,而限流模式则可以称为预防模式。限流模式主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。这种模式不能解决服务依赖的问题,只能解决系统整体资源分配问题,因为没有被限流的请求依然有可能造成雪崩效应。

5、Hystrix作用

  1. 请求超时降级,线程资源不足降级,降级之后可以返回自定义数据。
  2. 线程池隔离降级,分布式服务可以针对不同的服务使用不同的线程池,从而互不影响。
  3. 自动触发降级与恢复。
  4. 实现请求缓存和请求合并。

二、Hystrix搭建

1、服务提供者Module

项目名:cloud-provider-hystrix-payment8001

1、配置pom.xml

<dependencies>
    <!--新增hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>

    <dependency>
        <groupId>com.itan</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

2、配置application.yml

server:
  port: 8001

spring:
  application:
    name: cloud-provider-hystrix-payment

eureka:
  client:
    # 表示是否将自己注册进EurekaServer默认为true
    register-with-eureka: true
    # 表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    fetch-registry: true
    service-url:
      # 只向7001中注册,可以不用启动集群,方便操作
      defaultZone: http://eureka7001.com:7001/eureka/

3、主启动类

@SpringBootApplication
@EnableEurekaClient
public class Hystrix8001 {
    public static void main(String[] args) {
        SpringApplication.run(Hystrix8001.class,args);
    }
}

4、业务类impl

@Service
public class PaymentServiceImpl implements PaymentService {
    @Override
    public String PaymentService(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "paymentService_OK,id:" + id;
    }

    @Override
    public String timeOut(Integer id) {
        //模拟超时
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "paymentService_timeOut,id:" + id;
    }
}

5、controller类

@Slf4j
@RestController
@RequestMapping("hystrix")
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @Value("${server.port}")
    private String port;

    @PostMapping("ok")
    public String getOne(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = paymentService.ok(payment.getId());
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }

    @PostMapping("timeout")
    public String timeout(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = paymentService.timeOut(payment.getId());
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }
}

6、正常测试

1、启动Eureka7001
2、再启动Hystrix8001
3、调用两个接口,timeout接口会有延迟,但是两个都能正常访问

在这里插入图片描述

7、高并发下问题

1、在Jmter中测试,新建一个线程组,设置2w个线程

在这里插入图片描述

2、创建Http请求

在这里插入图片描述

3、设置HTTP请求头

在这里插入图片描述

4、当有大量访问的时候,无论接口一还是接口二,都会转圈圈

2、服务消费者Module

项目名:cloud-consumer-feign-hystrix-order80

1、配置pom.xml

<dependencies>
    <!--hystrix相关-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>

    <!--Feign相关-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>

    <dependency>
        <groupId>com.itan</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

2、配置application.yml

server:
  port: 80

eureka:
  # 设置服务名称信息(自定义)并设置访问路径可以显示 IP 地址
  instance:
    instance-id: hystrix80
    prefer-ip-address: true
  client:
    # 表示是否将自己注册进EurekaServer默认为true
    register-with-eureka: false
    # 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    # 客户端注册进 eureka 服务列表内
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

3、启动类

@SpringBootApplication
@EnableFeignClients
public class Hystrix80 {
    public static void main(String[] args) {
        SpringApplication.run(Hystrix80.class,args);
    }
}

4、Feign接口

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",configuration = {ProviderFeignClient.ProviderFeignClientConfigure.class})
public interface ProviderFeignClient {
    @PostMapping("hystrix/ok")
    String ok(Payment payment);

    @PostMapping("hystrix/timeout")
    String timeout(Payment payment);

    class ProviderFeignClientConfigure{
        //设置超时时间
        @Bean
        Request.Options options(){
            return new Request.Options(30000,60000);
        }
    }
}

5、controller

@Slf4j
@RestController
@RequestMapping("hystrix")
public class HystrixController {
    @Resource
    private ProviderFeignClient providerFeignClient;

    @PostMapping("ok")
    public String getOne(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = providerFeignClient.ok(payment);
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }

    @PostMapping("timeout")
    public String timeout(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = providerFeignClient.timeout(payment);
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }
}

6、正常测试

1、启动Hystrix80即可,因为注册中心和服务提供者上一步就已经启动了
2、调用两个接口

在这里插入图片描述

7、高并发下问题

还是和上面直接调用服务提供者接口一样,要么一直转圈圈,要么就报超时错误。

3、原因

1、8001同一层次的其他接口服务被困死,因为高并发下tomcat线程里面的工作线程已经被挤占完毕
2、80此时调用8001,客户端访问响应缓慢,转圈圈

4、解决策略

1、对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级
2、对方服务(8001)宕机了,调用者(80)不能一直卡死等待,必须有服务降级
3、对方服务(8001)OK,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者),自己处理降级

三、服务降级

1、概述

Hystrix服务降级,其实就是线程池中单个线程障处理,防止单个线程请求时间太长,导致资源长期被占有而得不到释放,从而导致线程池被快速占用完,导致服务崩溃。 整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。

2、提供者实现服务降级

设置自身调用超时时间的峰值,峰值内可以正常运行,超过了峰值时间需要有一个方案来处理,作服务降级fallback

1、在service中新建一个报错处理方法,在要处理的方法上加@HystrixCommand注解调用解决方法

public interface PaymentService {
    String ok(Integer id);

    String timeOut(Integer id);

    //报错处理方法
    String timeOutHandler(Integer id);
}
@Service
public class PaymentServiceImpl implements PaymentService {
    @Override
    public String ok(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "paymentService_OK,id:" + id;
    }

    /**
     * 一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
     * @param id
     * @return
     */
    @Override
    @HystrixCommand(fallbackMethod = "timeOutHandler",commandProperties = {
            //3s内就是正常的业务
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
    })
    public String timeOut(Integer id) {
        //故意制造异常
        int age = 10/0;
        //模拟超时
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "paymentService_timeOut,id:" + id;
    }

    @Override
    public String timeOutHandler(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "系统繁忙,请稍后再试";
    }
}

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

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class Hystrix8001 {
    public static void main(String[] args) {
        SpringApplication.run(Hystrix8001.class,args);
    }
}

3、测试

1、重启Hystrix8001服务
2、postman中调用超时方法,报错出现异常就会自动调用处理方法

在这里插入图片描述

3、消费者实现服务降级

Hystrix80服务也可以更好的保护自己,进行客户端的服务降级

1、配置application.yml

feign:
  hystrix:
    enabled: true #如果处理自身的容错就开启。开启方式与服务生产端不一样。

2、主启动类加@EnableHystrix

3、修改controller类

@Slf4j
@RestController
@RequestMapping("hystrix")
public class HystrixController {
    @Resource
    private ProviderFeignClient providerFeignClient;

    @PostMapping("ok")
    public String getOne(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = providerFeignClient.ok(payment);
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }

    @PostMapping("timeout")
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")  //3秒钟以内就是正常的业务逻辑
    })
    public String timeout(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        //故意制造异常
        int a = 10/0;
        String result = providerFeignClient.timeout(payment);
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }

    //兜底方法
    public String timeOutFallbackMethod(@RequestBody Payment payment){
        return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
    }
}

4、测试

1、重启Hystrix80服务
2、postman中调用超时方法,如果出现异常就会调用自身的兜底方法,如果是服务提供者出异常就会调用提供者的兜底方法

在这里插入图片描述

4、出现问题

如果每个业务方法,都对应一个兜底的方法,就会造成代码膨胀,很混乱,耦合度高,解决这样的问题,就是将统一和自定义的兜底方法区分开。

5、全局兜底方法

在类上使用@DefaultProperties(defaultFallback = "方法名")注解,统一跳转到全局处理方法,修改消费者的controller类中方法
@Slf4j
@RestController
@RequestMapping("hystrix")
@DefaultProperties(defaultFallback = "global")//调用全局方法
public class HystrixController {
    @Resource
    private ProviderFeignClient providerFeignClient;

    @PostMapping("ok")
    public String getOne(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = providerFeignClient.ok(payment);
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }

    @PostMapping("timeout")
//    @HystrixCommand(fallbackMethod = "timeOutFallbackMethod",commandProperties = {
//            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")  //3秒钟以内就是正常的业务逻辑
//    })
    @HystrixCommand//没有指明fallbackMethod的就用全局的兜底方法
    public String timeout(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        int a = 10/0;
        String result = providerFeignClient.timeout(payment);
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }

    //兜底方法
    public String timeOutFallbackMethod(@RequestBody Payment payment){
        return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
    }

    //全局兜底方法
    public String global(){
        return "服务提供者系统繁忙或已经宕机,请稍后重试";
    }
}

1、重启服务即可测试

6、将业务方法与处理方法分开

为服务消费者Hystrix80中的Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦,推荐使用这个方式

1、为80服务的ProviderFeignClient接口建一个实现类ProviderFeignClientImpl

@Component
public class ProviderFeignClientImpl implements ProviderFeignClient {
    @Override
    public String ok(Payment payment) {
        return "ok 方法故障";
    }

    @Override
    public String timeout(Payment payment) {
        return "timeout 方法故障";
    }
}

2、ProviderFeignClient接口@FeignClient注解加fallback属性

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",configuration = {ProviderFeignClient.ProviderFeignClientConfigure.class},fallback = ProviderFeignClientImpl.class)
public interface ProviderFeignClient {
    @PostMapping("hystrix/ok")
    String ok(Payment payment);

    @PostMapping("hystrix/timeout")
    String timeout(Payment payment);

    class ProviderFeignClientConfigure{
        //设置超时时间
        @Bean
        Request.Options options(){
            return new Request.Options(30000,60000);
        }
    }
}

3、去掉controller中的兜底方法

@Slf4j
@RestController
@RequestMapping("hystrix")
public class HystrixController {
    @Resource
    private ProviderFeignClient providerFeignClient;

    @PostMapping("ok")
    @HystrixCommand
    public String getOne(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = providerFeignClient.ok(payment);
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }

    @PostMapping("timeout")
    public String timeout(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = providerFeignClient.timeout(payment);
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }
}

4、测试

1、重启Hystrix80服务
2、正常测试发现可以
3、当停掉Hystrix8001服务后,再调用接口

在这里插入图片描述

4、此时服务端provider已经宕机了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器

四、服务熔断

1、什么是服务熔断

熔断机制是应对雪崩效应的一种微服务链路保护机制。
当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回"错误"的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。
在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是 @HystrixCommand

2、实现步骤

修改Hystrix8001项目

1、PaymentService新加两个方法

public interface PaymentService {
    String breaker(Integer id);

    String breaker_fallback(Integer id);
}

2、实现类

@Service
public class PaymentServiceImpl implements PaymentService {
    //服务熔断
    @HystrixCommand(fallbackMethod = "breaker_fallback",commandProperties = {
        @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),//是否开启断路器
        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "2"),//请求次数
        @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//时间范围
        @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "10"),//失败率达到多少后跳闸
    })
    @Override
    public String breaker(Integer id){
        if (id < 0){
            throw new RuntimeException("id不能负数");
        }
        String serialNumber = UUID.randomUUID().toString();
        return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber;
    }

    @Override
    public String breaker_fallback(Integer id){
        return "id不能负数,请稍候再试,id:" +id;
    }
}

3、controller类

@Slf4j
@RestController
@RequestMapping("hystrix")
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @Value("${server.port}")
    private String port;

    @PostMapping("breaker")
    public String breaker(@RequestBody Payment payment){
        log.info("入参:" + JSON.toJSONString(payment));
        String result = paymentService.breaker(payment.getId());
        log.info("出参:" + JSON.toJSONString(result));
        return result;
    }
}

4、测试

1、重启Hystrix8001服务
2、多次错误,然后慢慢正确,发现刚开始不满足条件,就算是正确的访问地址和参数也不能进行访问,需要慢慢的恢复链路。

在这里插入图片描述

3、原理

1、熔断类型
  1. 熔断打开:请求不再进行调用当前服务,内部设置时长一般为MTTR(平均故障处理时间),当打开时长达到所设时长则进入熔断状态。
  2. 熔断关闭:熔断关闭不会对服务进行熔断。
  3. 熔断半开:部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断。
2、断路器在什么情况下开始起作用
三个重要参数:

在这里插入图片描述

  1. 快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近10s。
  2. 请求总和阀值:在快照时间窗内,必须满足请求总和阀值才有资格熔断。默认为20,意味着在10s内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。
  3. 错误百分比阀值:当请求总数在快照时间窗内超过了阀值,比如发生了30次调用,如果在这30次调用中,有15次发生了异常,也就是超过50%的错误百分比,在默认设定50%阀值情况下,这时候断路器就会打开。
3、断路器开启或者关闭的条件
  • 当满足一定阀值的时候(默认10s内超过20个请求次数)。
  • 当失败率达到一定的时候(默认10s内超过50%的请求失败)。
  • 到达以上阀值,断路器将会开启。
  • 当开启的时候,所有请求都不会进行转发。
  • 一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。
4、断路器打开之后
  • 再有请求调用的时候,将不会调用主逻辑,而是直接调用降级fallback。通过断路器,实现了自动地发现错误并将降级逻辑切换为主逻辑,减少响应延迟的效果。
5、如何恢复断路之前
  • Hystrix也为我们实现了自动恢复功能。当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗,在这个时间窗内,降级逻辑是临时的变为主逻辑,当休眠时间窗到期,断路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将闭合,主逻辑恢复,如果这次请求依然有问题,断路器继续进入打开状态,休眠时间窗重新计时。

五、服务监控HystrixDashboard

1、概述

除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。

2、实现步骤

项目名:cloud-consumer-hystrix-dashboard

1、配置pom文件

<dependencies>
    <!--新增hystrix dashboard-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2、配置application.yml

server:
  port: 9001

3、主启动类上加@EnableHystrixDashboard 注解

@SpringBootApplication
@EnableHystrixDashboard
public class DashBoard9001 {
    public static void main(String[] args) {
        SpringApplication.run(DashBoard9001.class,args);
    }
}

4、所有Provider微服务提供方都需要配置监控依赖配置

<!-- actuator监控信息完善 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--web图形化-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

5、启动dashboard9001该服务监控消费端

访问:http://localhost:9001/hystrix

在这里插入图片描述

6、修改Hystrix8001服务的启动类

新版本Hystrix需要在主启动类中指定监控路径
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class Hystrix8001 {
    public static void main(String[] args) {
        SpringApplication.run(Hystrix8001.class,args);
    }

    /**
     * 此配置是为了服务监控而设置,与服务容错无关,springcloud升级后的坑
     * ServletRegistrationBean因为springboot的默认路径不是“/hystrix.stream”,
     * 只要在自己的项目里配置上下面的Servlet就可以了
     * @return
     */
    @Bean
    public ServletRegistrationBean getServlet(){
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

3、监控测试

1、重启Hystrix8001服务

2、重启DashBoard9001服务

3、9001监控8001

在这里插入图片描述

Delay:该参数用来控制服务器上轮询监控信息的延迟时间,默认为2000毫秒,可以通过配置该属性来降低客户端的网络和CPU消耗。
Title:该参数对应了头部标题Hystrix Stream之后的内容,默认会使用具体监控实例的URL,可以通过配置该信息来展示更合适的标题。

4、监控结果

先访问正确的,再访问错误的,再正确的,会发现图示断路器都是慢慢放开的
成功结果:http://localhost:8001/hystrix/breaker,id传入正数

在这里插入图片描述

失败结果:http://localhost:8001/hystrix/breaker,id传入负数

在这里插入图片描述

说明:
1、7色
2、1圈
  • 实心圆:共有两种含义。它通过颜色的变化代表了实例的健康程度,它的健康度从绿色<黄色<橙色<红色递减。
  • 该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大该实心圆就越大。所以通过该实心圆的展示,就可以在大量的实例中快速的发现故障实例和高压力实例。
3、1线
  • 曲线:用来记录2分钟内流量的相对变化,可以通过它来观察到流量的上升和下降趋势。
4、整图说明

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值