Spring Cloud学习记录 04Spring Cloud Hystrix 熔断器

Hystrix 熔断器

Hystrix 是一个用于分布式系统的 延迟容错 的开源库。在分布式系统里,许多依赖不可避免的调用失败,比如超时、异常等。Hystrix能够保证在一个依赖出问题的情况下,不会导致整个服务失败,避免级联故障,以提高分布式系统的弹性。

Hystrix 能为系统做:

  • 保护并控制通过第三方客户库访问的 延迟 和 故障(通常是通过网络访问的依赖关系)
  • 停止复杂分布式系统中的级联故障
  • 失败快速和快速恢复
  • 回退,并尽可能优雅地降级
  • 实现近实时监控、警报和操作控制

雪崩效应

在 分布式系统 中通常有多个服务进行调用,这一高并发的过程难免会有故障的时候,消费者一旦请求出现故障,请求会被堵塞,tomcat不会释放该线程,于是请求越来越多,最终导致服务器资源耗尽,形成了雪崩效应

提供者E 突然发生故障,导致线程堵塞

线程隔离&服务降级

线程隔离:将请求资源用 线程池 进行隔离,如果线程池已满,将不进行排队,直接判定为失败

服务降级:请求失败,会返回失败的提示(如 :对不起,网络太拥堵了
请求服务降级有以下两种的情况

  1. 被分配到已满的线程池
  2. 请求超时(超时时长自行配置

示例

代码在上篇文章的基础上进行添加编辑:Java学习记录 03Spring Cloud 负载均衡Ribbon

  1. 消费者 添加依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
  2. 消费者 启动类 ,添加注解 @EnableCircuitBreaker

    // @EnableDiscoveryClient // Eureka客户端
    // @EnableCircuitBreaker  // 熔断器
    // @SpringBootApplication
    // 该注解组合以上3个注解
    @SpringCloudApplication
    public class ConsumerApplication {
        // ....
    }
    

    @SpringCloudApplication 注解整合了 Eureka、Hystrix、启动器 注解

  3. 消费者 服务降级处理 ,controller

    降级处理有两种方式:

    方式注解用于优点
    1@HystrixCommand(fallbackMethod = "{降级服务的方法名}")方法降级服务的方法可获取方法的参数
    2@DefaultProperties (defaultFallback = "{降级服务的方法名}")类、接口、枚举、Annotation类型可统一降级服务,降低维护成本
    @RestController
    @RequestMapping("consumer")
    @Slf4j
    // 方式2.1 多接口响应
    @DefaultProperties (defaultFallback = "defaultFallback")
    public class ConsumerController {
        
        @Autowired
        private RestTemplate restTemplate;
        
        //...
        
        @RequestMapping("{id}")
        // 方式1.1 单个接口响应
        // @HystrixCommand(fallbackMethod = "queryByIdFallback")
        // 方式2.2
        @HystrixCommand
        public String findById(@PathVariable Long id) throws InterruptedException {
            String url = "HTTP://user-service/user/"+id;
            return restTemplate.getForObject(url , String.class);
        }
        
        // 方式1.2(方式1有参数接收,因 方式1 写在方法里!
        public String queryByIdFallback(Long id) {
            log.error("查询信息失败1,id : {}",id);
            return "对不起,网络太拥堵了!(Test1";
        }
        
        // 方式2.3
        public String defaultFallback() {
            log.error("查询信息失败2");
            return "对不起,网络太拥挤了!(Test2";
        }
        
    }
    

    修改了 findById()方法 的返回值,从 提供者 那获取也是json格式,为了也方便降级数据的返回,因此返回值为String

  4. 测试

    1. 依次打开 Eureka、server、consumer 三个服务
    2. 访问 http://localhost:8080/consumer/1 (返回 数据
    3. 关闭 server 再次访问以上请求
    4. 页面返回:"对不起,网络太拥挤了!(Test2 " (成功降级服务处理

超时设置

  1. 消费者 application.yml ,添加超时配置

    # 请求超过2s回返回错误,默认1s(测试用
    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
    
  2. 提供者 controller 休眠 (只为触发超时
    休眠写 被调用服务的方法里

    @RequestMapping("{id}")
    public User findById(@PathVariable Long id) {
        /* 
           测试 : 超时请求延迟 
           识别判断:保留1为小数
        */
        Thread.sleep(2000);
        // Thread.sleep(1900);
        return service.findById(id);
    }
    
  3. 测试

    1. 依次打开 Eureka、server、consumer 三个服务
    2. 打开浏览器F12 检查请求的时长,访问 http://localhost:8080/consumer/1 (返回 数据
    3. 休眠2s返回结果:"对不起,网络太拥挤了!(Test2 " (成功降级服务处理
    4. 休眠1.9s返回结果:数据

熔断器

熔断器它会在一段时间内检测请求异常,如果末段时间内异常超出一定比例时,则迫使请求进行 降级服务 ,并非 调用提供者,从而防止更多请求发生同样的失败操作。一旦触发熔断器打开,需要等待休眠,休眠结束后会释放少部分请求进行测试,如果还是出现问题,则继续打开熔断器,否则关闭熔断器

日常例子:

好比家用的漏电开关,一旦电压不稳定,就打开电闸,断开电源

熔断器计算 出来的状态分别有:

  • Closed (关闭):所有请求正常访问
  • Open (打开):所有请求降级服务
  • Half-Open (半打开):当打开的熔断器休眠结束后,会释放部分请求,如果都是健康,就关闭熔断器,否则保持打开熔断器

熔断器的 默认配置&触发条件:

  • 最小请求次数 20次
  • 异常比例阈值 50%
  • 熔断休眠时长 5s

解释:5s内访问次数20次,如果超过10次的是异常,则打开熔断器 休眠5s

示例

在以上代码的基础上进行编辑

  1. 消费者 controller 制造异常 (上面的 hystrix依赖 也要有!!!)

    @RequestMapping("{id}")
    @HystrixCommand
    public String findById(@PathVariable Long id) throws InterruptedException {
    
        // 测试 :异常制造 (实现熔断器报错预期
        if (id == 1) {
            throw new RuntimeException("忙碌");
        }
        
       	//..
        
        String url = "HTTP://user-service/user/"+id;
        
        return restTemplate.getForObject(url , String.class);
    }
    

    注意:上面测试代码,如果打开有休眠,先清空添加的休眠代码

  2. 测试
    流程:先访问 请求1 20+次 (制造异常触发熔断器),然后在访问 请求2 (访问失败)

    1. 触发阈值的请求:http://localhost:8080/consumer/1 (注定失败
    2. 测试熔断的请求:http://localhost:8080/consumer/2 (测试熔断

    熔断器的触发条件上面说有,就不赘述了

配置熔断策略

修改熔断器的 默认配置:

# 熔断触发最小请求次数,默认值是20
hystrix.command.default.circuitBreaker.requestVolumeThreshold=10
# 熔断后休眠时长,默认值5000ms
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=10000
# 触发熔断错误比例阈值,默认值50%
hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
# 请求超过2s回返回错误,默认1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000

以上配置可自行尝试调用


仓库代码 : https://gitee.com/Sanscan12/spring-cloud-examples.git

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值