6 、熔断器 Spring Cloud Hystrix

本文介绍了Spring Cloud Hystrix组件,用于防止微服务中的雪崩效应。通过服务降级和线程隔离策略,Hystrix提供了一种处理服务故障的方法。文中详细讲解了Hystrix的工作原理,包括熔断器的三种状态及其转换,并通过实例展示了如何配置和使用Hystrix进行局部和全局服务降级,以及超时和请求量触发的熔断策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hystrix 简介

Hystrix,英文意思是豪猪,全身是刺,刺是一种保护机制。Hystrix也是Netflix公司的一款组件。

Hystrix的作用是什么?:实现服务熔断降级处理,保护微服务,防止雪崩效应发生。

Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库、防止出现级联失败也就是雪崩效应

雪崩效应

什么是雪崩效应?

 1.微服务中,一个请求可能需要多个微服务接口才能实现,会形成复杂的调用链路。
 2.如果某服务出现异常,请求阻塞,用户得不到响应,容器中线程不会释放,于是越来越多用户请求堆积,越来越多线程阻塞。
 3.单服务器支持线程和并发数有限,请求如果一直阻塞,会导致服务器资源耗尽,从而导致所有其他服务都不可用,从而形成雪崩效应;

Hystrix解决雪崩问题的手段,主要是服务降级(兜底),线程隔离;

熔断原理分析

熔断器的原理很简单,如同电力过载保护器。

熔断器状态机有3个状态:

 1.Closed:关闭状态,所有请求正常访问
 2.Open:打开状态,所有请求都会被降级。
   Hystrix会对请求情况计数,当一定时间失败请求百分比达到阈(yu:四声)值(极限值),则触发熔断,断路器完全关闭
   默认失败比例的阈值是50%,请求次数最低不少于20次,巧记,一半一半,5,20
 3.Half Open:半开状态
   Open状态不是永久的,打开一会后会进入休眠时间(默认5秒)。休眠时间过后会进入半开状态。
   半开状态:熔断器会判断下一次请求的返回状况,如果成功,熔断器切回closed状态。如果失败,熔断器切回open状态。
 threshold reached 到达阈值
 under threshold  阈值以下

 

熔断器的核心:线程隔离和服务降级。

 1.线程隔离:是指Hystrix为每个依赖服务调用一个小的线程池,如果线程池用尽,调用立即被拒绝,默认不采用排队。
 2.服务降级(兜底方法):优先保证核心服务,而非核心服务不可用或弱可用。触发Hystrix服务降级的情况:线程池已满、请求超时。

线程隔离和服务降级之后,用户请求故障时,线程不会被阻塞,更不会无休止等待或者看到系统奔溃,至少可以看到执行结果(熔断机制)。

局部熔断/服务降级案例

目标:服务提供者的服务出现了故障,服务消费者快速失败给用户友好提示。体验服务降级

降级:某个方法发生故障,则返回默认的数据给用户,此时叫服务降级。

实现步骤:

(1)引入熔断的依赖坐标:

user-consumer中加入依赖

 <!--熔断器-->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
 </dependency>

(2)开启熔断的注解

修改user-consumercom.sen.UserConsumerApplication,在该类上添加@EnableCircuitBreaker,

(3)服务降级处理

user-consumercom.sen.controller.UserController中添加降级处理方法,方法如下:

 /**
  * 服务降级处理方法
  * @return
  */
 public User failBack(Integer id){
     User user = new User();
     user.setUsername("服务降级,默认处理!");
     return  user;
 }

在有可能发生问题的方法上添加降级处理调用,例如在queryById方法上添加降级调用,代码如下:

(4)测试

将服务提供者的服务全部停掉,启动eureka-serveruser-consumer,然后请求<http://localhost:18082/consumer/1>测试效果可以看出降级方法调用了

 

上面将将服务提供者停掉来测试服务不可用走降级方法,其实我建议不停掉也行,增加一个id=3的运行时异常来测试↓

 package com.sen.controller;
 ​
 import com.sen.bean.User;
 import com.sen.service.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 ​
 @RestController
 @RequestMapping("/user")
 public class UserController {
     @Autowired
     private UserService userService;
 ​
     @RequestMapping("/find/{id}")
     public User find(@PathVariable Integer id) throws InterruptedException {
         //http://localhost:18081/user/find/1User
         if (id==3){
             throw new RuntimeException("id错误");
         }
 ​
         //Thread.sleep(5000);
 ​
         return userService.findUserById(id);
     }
 }

 其他熔断策略配置,

 1. 熔断后休眠时间:sleepWindowInMilliseconds
 2. 熔断触发最小请求次数:requestVolumeThreshold
 3. 熔断触发错误比例阈值:errorThresholdPercentage
 4. 熔断超时时间:timeoutInMilliseconds

消费者user-consumer配置如下↓

 # 配置熔断策略:
 hystrix:
   command:
     default:
       circuitBreaker:
         # 强制打开熔断器 默认false关闭的。测试配置是否生效
         forceOpen: false
         # 触发熔断错误比例阈值,默认值50%!!!
         errorThresholdPercentage: 50
         # 熔断后休眠时长,默认值5秒,即睡眠5秒去看服务如果没有问题,熔断器由半开到关闭,恢复服务的访问
         sleepWindowInMilliseconds: 10000
         # 熔断触发最小请求次数,默认值是20,即请求访问服务,服务出现错误2次开始触发熔断全开
         requestVolumeThreshold: 2
       execution:
         isolation:
           thread:
             # 熔断降级超时设置,默认为1秒,即访问服务耗时超过1秒就服务降级
             timeoutInMilliseconds: 2000

为了测试效果更明显,建议先测timeoutInMilliseconds再测forceOpen,最后三个以requestVolumeThreshold测↑

(1)超时时间测试

a.修改user-providercom.sen.controller.UserControllerfindById方法,让它休眠3秒钟。

b.修改user-consumer的application.yml,设置超时时间5秒,此时不会熔断。

       execution:
         isolation:
           thread:
             # 熔断降级超时设置,默认为1秒,即访问服务耗时超过1秒就服务降级
             timeoutInMilliseconds: 2000

c.如果把超时时间改成2000,此时就会熔断。

(2)熔断触发最小请求次数测试

a.修改user-providercom.sen.controller.UserController,在方法中制造异常,代码如下:

b.3次并发请求<http://localhost:18082/consumer/1>,会触发熔断

再次请求<http://localhost:18082/consumer/2>的时候,也会熔断,5秒钟会自动恢复。

并发请求建议使用jmeter工具。

忘了局部降级方法和全局降级方法的使用,打开@HystrixCommand注解里面看

<!--注意:因为熔断的降级逻辑方法跟正常逻辑方法一样,必须保证相同的参数列表和返回值相同-->

两种编写方式:编写在类上,编写在方法上。在类的上边对类的所有方法都生效。在方法上,仅对当前方法有效。

(1)方法上服务降级的fallback兜底方法

 使用HystrixCommon注解,定义
 @HystrixCommand(fallbackMethod="failBack")用来声明一个降级逻辑的fallback兜底方法

(2)类上默认服务降级的fallback兜底方法

 刚才把fallback写在了某个业务方法上,如果方法很多,可以将FallBack配置加在类上,实现默认FallBack
 @DefaultProperties(defaultFallback=”defaultFailBack“)//在类上,指明统一的失败降级方法;

(3)案例

a.在user-consumercom.sen.controller.UserController类中添加一个全局熔断方法:

 /**
  * 全局的服务降级处理方法
  * @return
  */
 public User defaultFailBack(){
     User user = new User();
     user.setUsername("Default-服务降级,默认处理!");
     return  user;
 }

b.在queryById方法上将原来的@HystrixCommand相关去掉,并添加@HystrixCommand注解:

 @HystrixCommand
 @GetMapping(value = "/{id}")
 public User queryById(@PathVariable(value = "id")Integer id){
     //...略
     return  user;
 }

c.在user-consumercom.sen.controller.UserController类上添加

@DefaultProperties(defaultFallback = "defaultFailBack")

 

d.测试访问<http://localhost:18082/consumer/1>,效果如下:

 小结

  • Hystrix的作用:用于隔离访问远程服务、第三方库、防止出现级联失败也就是雪崩效应。

  • 理解雪崩效应:

     1.微服务中,一个请求可能需要多个微服务接口才能实现,会形成复杂的调用链路。
     2.如果某服务出现异常,请求阻塞,用户得不到响应,容器中线程不会释放,于是越来越多用户请求堆积,越来越多线程阻塞。
     3.单服务器支持线程和并发数有限,请求如果一直阻塞,会导致服务器资源耗尽,从而导致所有其他服务都不可用,从而形成雪崩效应;
  • 知道熔断器的3个状态以及3个状态的切换过程

     1.Closed:关闭状态,所有请求正常访问
     2.Open:打开状态,所有请求都会被降级。
       Hystrix会对请求情况计数,当一定时间失败请求百分比达到阈(yu:四声)值(极限值),则触发熔断,断路器完全关闭
       默认失败比例的阈值是50%,请求次数最低不少于20次
     3.Half Open:半开状态
       Open状态不是永久的,打开一会后会进入休眠时间(默认5秒)。休眠时间过后会进入半开状态。
       半开状态:熔断器会判断下一次请求的返回状况,如果成功,熔断器切回closed状态。如果失败,熔断器切回open状态。
     threshold reached 到达阈(yu:四声)值
     under threshold  阈值以下
  • 能理解什么是线程隔离,什么是服务降级

     1.线程隔离:是指Hystrix为每个依赖服务调用一个小的线程池,如果线程池用尽,调用立即被拒绝,默认不采用排队。
     2.服务降级(兜底方法):优先保证核心服务,而非核心服务不可用或弱可用。触发Hystrix服务降级的情况:线程池已满、请求超时。
  • 能实现一个局部方法熔断案例

     1.定义一个局部处理熔断的方法failBack()
     2.在指定方法上使用@HystrixCommand(fallbackMethod = "failBack")配置调用
  • 能实现全局方法熔断案例

     1.定义一个全局处理熔断的方法defaultFailBack()
     2.在类上使用@DefaultProperties(defaultFallback = "defaultFailBack")配置调用
     3.在指定方法上使用@HystrixCommand

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值