Spring-Cloud之Hystrix

2021年11月20日 阅读数:2
这篇文章主要向大家介绍Spring-Cloud之Hystrix,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

原文地址:https://blog.vchar.top/java/1624363200.htmlhtml

系统负载太高,突发流量或网络等各类异常状况,经常使用解决方案以下:java

  • 限流:对访问量进行限制,防止流量太大直接使整个服务发生故障;
  • 熔断:为了防止整个系统故障,中止出现问题的服务的访问;
  • 降级:抛弃一些非核心的接口和数据;
  • 熔断和降级互相交集:
    • 相同点:从可用性和可靠信息出发,为防止系统崩溃;最终让用户体验到的是某些功能暂时不可用
    • 不一样点:服务熔断通常是下游服务故障致使,而服务降级通常是从整个系统负荷考虑,由调用方控制

Hystrix的简介

Netflix的Hystrix(豪猪)经过对调用的服务进行资源隔离,实现熔断降级的功能,提高分布式系统的可用性和稳定性。git

设计原则

hystrix为了实现高可用性的架构,设计hystrix的时候,遵循了如下这些设计原则:github

  • 对依赖服务调用时出现的调用延迟和调用失败进行控制和容错保护;
  • 在复杂的分布式系统中,阻止某一个依赖服务的故障在整个系统中蔓延;若有以下调用链:服务A->服务B->服务C,当服务C发生故障时,若是没作处理那么服务B和服务A都会受到影响发生故障,致使整套分布式系统所有故障、总体宕机。
  • 提供fail-fast(快速失败)和快速恢复的支持;
  • 提供fallback优雅降级的支持;
  • 支持近实时的监控、报警以及运维操做;

具体实现细节:web

  • 阻止任何一个依赖服务耗尽全部的资源,好比tomcat中的全部线程资源
  • 避免请求排队和积压,采用限流和fail fast来控制故障
  • 提供fallback降级机制来应对故障
  • 使用资源隔离技术,好比Bulkhead(舱壁隔离技术),Swimlane(泳道技术),circuit breaker(短路技术),来限制任何一个依赖服务的故障的影响
  • 经过近实时的统计/监控/报警功能,来提升故障发现的速度
  • 经过近实时的属性和配置热修改功能,来提升故障处理和恢复的速度
  • 保护依赖服务调用的全部故障状况,而不只仅只是网络故障状况

实现的方案的简述

  • Hystrix经过外部依赖的访问请求进行封装,让其运行在独立的线程中达到资源隔离的目的;
  • 对请求的处理时间进行监控,若是超过设置的阀值那么会直接让其超时返回,不容许其耗费过长的时间阻塞住;
  • 为每一个依赖服务维护一个独立的线程池,当线程池满了的时候就会直接拒绝这个服务的调用;
  • 统计依赖服务的调用状况,好比成功数、失败数、拒绝次数、超时次数等;
  • 根据依赖服务的调用状况,自动判断其健康状态,若是失败次数超过阀值自动进行熔断(在必定时间内直接对该服务进行降级(也就是在调用的时候直接返回失败),一段时间后再自动恢复尝试);
  • 当一个服务调用出现失败,被拒绝,超时,短路等异常状况时,自动调用fallback降级机制;
  • 对属性和配置的修改提供近实时的支持;

这里顺便提一下:feign中它本身其实也有fallback降级机制(只是功能没有那么强大),好比若是依赖服务发生故障时虽然有fallback降级机制,可是仍是会将请求向该服务发送(该等待的时间依然会等待);spring

当咱们引入Hystrix并启用后,feign中的fallback降级机制将交给Hystrix来实现,而Hystrix会在监控到服务调用发生故障时,它会判断其失败次数,若是超过阀值,在一段时间内其它服务调用它的时候会直接返回降级处理策略,不会再向该服务发送请求了。tomcat

Hystrix 使用示例

下面咱们经过一些示例让你快速了解它的基本使用。示例使用的Spring-Cloud的版本是Hoxton.SR8,Spring-Boot的版本是2.3.4.RELEASE。示例项目的源代码网络

相关依赖和配置

添加以下maven的依赖(注意feign的请自行添加,feign的使用参考: https://blog.vchar.top/java/1621167133.html架构

<!-- hystrix的依赖-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

而后在启动类上添加以下注解:@EnableCircuitBreaker 或者是 @EnableHystrix ; 效果都是同样的(@EnableHystrix继承了@EnableCircuitBreaker注解)。app

单独使用 hystrix

经过添加@HystrixCommand注解可让该方法被hystrix监控到实现熔断降级策略。

示例1:在controller中直接添加熔断降级处理方式

@HystrixCommand(fallbackMethod = "hystrixMethodDemoFail")
    @GetMapping("/demo1")
    public Train findTrain(){
        System.out.println("执行...");
        // 这里发送异常时会自动执行hystrixMethodDemoFail方法
        return this.hystrixDemoService.hystrixMethodDemo();
    }

    /**
     * 这里必定要和HystrixCommand注解中的方法一致,且参数也必须一致;当服务异常时会调用此方法
     */
    private Train hystrixMethodDemoFail(){
        System.out.println("调用异常");
        return null;
    }
}

示例2:在service中直接添加熔断降级处理方式

@HystrixCommand(fallbackMethod = "hystrixMethodDemo2Fail")
@Override
public Train hystrixMethodDemo2() {
    System.out.println("hystrixMethodDemo2 调用feign服务:trainFeignClient.findTrain()");
    return this.trainFeignClient.findTrain();
}

private Train hystrixMethodDemo2Fail(){
    System.out.println("hystrixMethodDemo2Fail ...");
    return null;
}

示例3:方法间的调用

@Override
public Train hystrixMethodDemo3() {
    // hystrixMethodDemo2作了熔断降级的
    return this.hystrixMethodDemo2();
}

由于hystrix是经过AOP来实现的;所以一个类的方法间调用时不会生效的。

结合feign使用hystrix

feign以前的写法不用改变,继续保持便可;只须要添加以下配置就能够将feign的熔断降级处理的方式切换到hystrix:

feign:
  hystrix:
    # 启用feign中的hystrix
    enabled: true

hystrix的监控界面

添加下面的maven依赖:

<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>

在启动类上添加注解: @EnableHystrixDashboard ;而后添加以下配置:

management:
  endpoints:
    web:
      exposure:
        include: "*"

而后访问监控界面:http://localhost:8100/hystrix ;在里面输入 http://localhost:8100/actuator/hystrix.stream 点击 Monitor Stream进入监控界面。