本文主要是介绍Hystrix熔断降级组件学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Hystrix熔断降级组件学习
- 一、Hystrix是什么?
- 二、Hystrix的作用
- 三、Spring Cloud整合Hystrix代码示例
- 3.1. 添加依赖
- 3.2. 启用Hystrix
- 3.3. 定义服务调用
- 四、熔断器仪表盘
- 4.1. 添加依赖
- 4.2. 启用Hystrix Dashboard
- 4.3. 访问Dashboard(仪表盘)
- 五、Spring Cloud整合Hystrix原理
- 5.1. 整合入口
- 5.2 HystrixCommandAspect
- 5.3 Hystrix的断路器配置
- 5.4 Hystrix隔离机制原理
一、Hystrix是什么?
Hystrix是由Netflix开源的一个容错框架,主要用于处理分布式系统中的故障和延迟,以提高系统的弹性和稳定性。它通过服务降级、服务熔断、依赖隔离和实时监控等功能,在复杂的分布式系统中提供断路器模式来阻止级联失败,并提供回退机制来增强系统的弹性。
在微服务架构中,服务间的调用变得非常频繁和复杂。当某个服务出现故障时,如果不加以控制,很容易引发级联故障,导致整个系统崩溃。Hystrix通过服务降级、熔断和依赖隔离等机制,有效防止了这种情况的发生,提高了系统的稳定性和可靠性。
二、Hystrix的作用
Hystrix是Netflix开源的一个服务隔离组件,主要用于处理分布式系统的延迟和容错。它具备以下主要功能:
- 熔断器模式:当某个服务的失败率达到一定阈值时,Hystrix会自动触发熔断,阻止对该服务的进一步请求,从而避免系统资源的无谓消耗。
- 服务降级:在熔断器开启后,Hystrix会执行服务降级逻辑,返回预设的默认值或缓存数据,以保证服务的部分可用性。
- 资源隔离:通过线程池或信号量对服务调用进行隔离,限制任何一个依赖的影响范围,防止单个服务故障耗尽整个系统的资源。
- 实时监控与告警:提供近实时的监控和告警功能,帮助开发者及时发现并解决问题。
三、Spring Cloud整合Hystrix代码示例
3.1. 添加依赖
首先,需要在项目的构建文件(如Maven或Gradle)中添加Hystrix的依赖项。以Maven为例:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.5.RELEASE</version>
</dependency>
3.2. 启用Hystrix
在Spring Boot的主类或配置类上添加@EnableHystrix
注解来启用Hystrix。
3.3. 定义服务调用
在服务调用时,使用@HystrixCommand
注解来标记需要容错处理的方法,并指定一个回退方法(fallback method)。
@RestController
@RequestMapping("/api")
public class MyController { @Autowired private MyService myService; @GetMapping("/user/test") @HystrixCommand(fallbackMethod = "sayHelloFallBack")public String testUser(@RequestParam Integer userId) { return myService.getUserInfo(userId); } public String sayHelloFallBack(Integer userId) { return "Service is down, please try again later."; }
} @Service
public class MyService { @Autowired private RestTemplate restTemplate; public String getUserInfo(Integer userId) { // 假设这里调用远程服务 String url = "http://example.com/api/users/{userId}"; return restTemplate.getForObject(url, String.class, userId); }
}
四、熔断器仪表盘
在Spring Cloud中整合Hystrix Dashboard来监控微服务中的Hystrix熔断器状态是一个常见的做法。以下是一个简单的示例,展示如何将Hystrix Dashboard与Spring Cloud应用整合起来。
4.1. 添加依赖
首先,确保你的Spring Boot项目中已经添加了Spring Cloud Starter Hystrix和Spring Cloud Starter Hystrix Dashboard的依赖。以下是一个Maven示例:
<!-- Spring Cloud Hystrix Dashboard -->
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> <version>2.2.5.RELEASE</version>
</dependency>
注意:替换你的Spring Cloud版本
为你项目中实际使用的Spring Cloud版本。
4.2. 启用Hystrix Dashboard
在你的Spring Boot应用的主类或配置类上添加@EnableHystrixDashboard
注解来启用Hystrix Dashboard。
4.3. 访问Dashboard(仪表盘)
在Spring Cloud中,Hystrix会自动注册一个/hystrix.stream
端点,启动你的Spring Boot应用,并访问Hystrix Dashboard的URL(通常是http://ip:port/hystrix
)
在Dashboard页面上,输入你的Metrics Stream的URL(例如,http://ip:port/hystrix.stream
),然后点击“Monitor Stream”按钮。
比如我的应用是127.0.0.1:8801/hystrix.stream
上述请求报错,是因为hystrix整合springBoot 2.0以及之后的版本需要额外配置一些东西(Hystrix 目前处于停更维护阶段,springCloud 整合限流组件更常见的是Sentinel)
配置yaml
指定哪些主机地址的Hystrix.stream可以被Hystrix Dashboard访问。这是出于安全考虑,防止未授权的访问尝试,从而保护系统的敏感信息和运行数据。
hystrix:dashboard:proxyStreamAllowList: localhost,127.0.0.1
注册Metric servlet
如果我们的SpringBoot是2.0以后版本,然后需要添加 ServletRegistrationBean 因为springboot的默认路径不是 “/hystrix.stream”。
@Beanpublic ServletRegistrationBean getServlet() {HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);registrationBean.setLoadOnStartup(1);registrationBean.addUrlMappings("/hystrix.stream");registrationBean.setName("HystrixMetricsStreamServlet");return registrationBean;}
接着请求业务接口,该stream就可以查看请求监控信息了。
五、Spring Cloud整合Hystrix原理
本篇博文是在使用Hystrix的版本为2.2.5.RELEASE + springCloud 版本Hoxton.SR8下分析得出,不同版本可能有所差异,请读者谨慎辨别
springCloud整合Hystrix的步骤有三个
- 引入依赖(分析原理方式:其引入的依赖的自动装配类)
- 启动类使用**@EnableHystrix**(分析原理的方式:@EnableHystrix做了哪些操作)
- 需要配置熔断、降级的方式添加**@HystrixCommand** (分析原理的方式:@HystrixCommand做了哪些操作)
5.1. 整合入口
- @EnableHystrix
@EnableHystrix
注解来启用Hystrix。这个注解会触发Spring Cloud的自动配置机制,加载与Hystrix相关的配置和Bean。
- 自动装配类
自动装配类 | 实例化的bean | 作用 |
---|---|---|
HystrixAutoConfiguration | HystrixHealthIndicator | 用于监控Hystrix的健康状态,比如断路器状态,请求的成功率 |
HystrixWebfluxEndpoint | 为基于响应式编程模型的Spring Boot应用提供了Hystrix的端点,Hystrix主要设计用于同步的阻塞式调用,而WebFlux是基于响应式的非阻塞模型,使用过程中可能会有限制 | |
HystrixStreamEndpoint | 这是一个用于暴露Hystrix实时指标的端点,实时监控Hystrix的状态和指标 | |
HystrixMetricsBinder | 用于将Hystrix的度量指标(如请求成功率、失败率、响应时间等)绑定到Spring Boot的Micrometer度量系统中 | |
HystrixCircuitBreakerAutoConfiguration | HystrixCircuitBreakerFactory | 创建断路器实例 管理断路器状态 关闭(close)、打开(open)、半开(half-open) |
ReactiveHystrixCircuitBreakerAutoConfiguration | ReactiveHystrixCircuitBreakerFactory | 这个自动装配类专门为响应式编程环境(如使用Spring WebFlux的应用)配置Hystrix的断路器。它允许在响应式流中利用Hystrix的断路器模式来保护远程服务调用。 |
HystrixSecurityAutoConfiguration | 与Hystrix和安全性相关的自动装配类 | |
HystrixCircuitBreakerConfiguration | HystrixCommandAspect | 这个切面(Aspect)负责处理带有@HystrixCommand 注解的方法,从而在方法执行时自动应用断路器的逻辑。 |
HystrixShutdownHook | 应用程序关闭时执行特定清理任务的组件 |
- @HystrixCommand
在 Spring Cloud 中,Hystrix 通常与 Spring Cloud Netflix 的 spring-cloud-starter-netflix-hystrix
依赖一起使用。整合的关键在于通过 Spring 的 AOP(面向切面编程)特性来包装服务调用,以便在调用失败时能够执行回退逻辑。
当 Spring 容器启动时,它会扫描所有带有 @HystrixCommand
注解的方法,并使用 AOP 技术创建一个代理。这个代理会在实际方法调用之前和之后插入逻辑,以处理断路器的逻辑(如是否允许调用、记录调用结果、触发回退等)。
5.2 HystrixCommandAspect
Hystrix整合的关键是AOP,HystrixCommandAspect就是Hystrix为我们生成AOP的入口类,见名知意,该类是处理 @HystrixCommand
的一个切面类。
@Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()")public Object methodsAnnotatedWithHystrixCommand(ProceedingJoinPoint joinPoint) throws Throwable {//获取被代理的目标方法(原始方法),AOP代理可能会改变方法的签名或行为。Method method = AopUtils.getMethodFromTarget(joinPoint);Validate.notNull(method, "failed to get method from joinPoint: %s", new Object[]{joinPoint});//方法不能同时被@HystrixCommand和@HystrixCollapser修饰if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) {throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser annotations at the same time");} else {//根据方法的注解类型(@HystrixCommand或@HystrixCollapser),从META_HOLDER_FACTORY_MAP中获取相应的//MetaHolderFactory,并创建MetaHolder实例。MetaHolder用于封装与Hystrix命令执行相关的元数据。MetaHolderFactory metaHolderFactory = (MetaHolderFactory)META_HOLDER_FACTORY_MAP.get(HystrixCommandAspect.HystrixPointcutType.of(method));MetaHolder metaHolder = metaHolderFactory.create(joinPoint);//创建HystrixInvokable:这个实例封装了实际要执行的方法调用。HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ? metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();try {Object result;if (!metaHolder.isObservable()) {//@HystrixCommand 默认非观察着模式处理CommandExecutor.execute() 我们的常用模式result = CommandExecutor.execute(invokable, executionType, metaHolder);} else {//@HystrixCollapser 注解使用的是观察模式处理//可观察的(响应式编程中的概念,表示数据流的源,允许观察者订阅以接收数据更新)result = this.executeObservable(invokable, executionType, metaHolder);}//返回执行结果return result;} catch (HystrixBadRequestException var9) {//省略异常处理}}}
5.3 Hystrix的断路器配置
隔离:Hystrix 通过线程池或信号量将远程服务调用隔离开来,防止一个服务的失败影响到其他服务的调用。
快速失败:当检测到服务故障时,Hystrix 会迅速让请求失败,并调用回退逻辑,而不是让请求长时间等待或导致系统资源耗尽。
资源控制:通过限制并发请求的数量,Hystrix 可以防止某个服务消耗过多资源,影响系统的整体性能。
隔离策略:线程池配置
配置项 | 描述 | 默认值 |
---|---|---|
hystrix.command.default.execution.isolation.strategy | 设置默认的隔离策略,THREAD 表示线程池隔离 | THREAD |
hystrix.command.default.execution.isolation.thread .timeoutInMilliseconds | 线程池隔离下,命令执行的超时时间(毫秒) | 默认值取决于具体实现,通常为1秒或更长 |
hystrix.command.default.execution.isolation.thread.coreSize | 线程池的核心线程数,即线程池始终维持的活跃线程数 | 10(但可能因版本或配置而异,需根据实际情况调整) |
hystrix.command.default.execution.isolation.thread.maximumSize | 线程池允许的最大线程数,用于应对高并发情况 | 10(但可能因版本或配置而异,需根据实际情况调整) |
hystrix.command.default.execution.isolation.thread .queueSizeRejectionThreshold | 线程池队列拒绝阈值,当队列中的等待任务数超过此值时,即使没有达到maximumSize ,也会拒绝新的命令 | 5(但需注意,当maxQueueSize 小于等于0时,此配置无效) |
hystrix.command.default.execution.isolation.thread.maxQueueSize | 线程池阻塞队列的最大长度,用于控制队列中可等待的任务数 | -1(使用SynchronousQueue ,不存储排队数据;大于0时使用LinkedBlockingQueue ) |
hystrix.command.default.execution.isolation.thread. keepAliveTimeMinutes | 线程池中非核心线程的空闲存活时间(分钟),超过此时间后非核心线程将被终止 |
隔离策略:信号量配置
配置项 | 描述 | 默认值 |
---|---|---|
hystrix.command.default.execution.isolation.strategy | 设置默认的隔离策略,SEMAPHORE 表示信号量隔离 | 非 THREAD (因为默认是线程池隔离,所以信号量隔离需显式指定) |
hystrix.command.default.execution.isolation.semaphore. maxConcurrentRequests | 信号量隔离下,同时执行的最大命令数(即信号量的最大值) | 无固定默认值,需根据业务场景和服务器资源来配置 |
断路器开关配置
配置项 | 描述 | 默认值 |
---|---|---|
hystrix.command.default.circuitBreaker.enabled | 是否启用断路器功能。设置为true 时启用,false 时禁用。 | true |
hystrix.command.default.circuitBreaker.requestVolumeThreshold | 触发断路器打开之前,必须达到的最小请求量。 | 默认值可能因版本而异,但通常是一个较低的值(如20) |
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds | 断路器打开后,等待多久尝试恢复服务(半开状态测试周期)。 | 默认值可能因版本而异,但通常是一个合理的等待时间(如5000毫秒) |
hystrix.command.default.circuitBreaker.errorThresholdPercentage | 在requestVolumeThreshold 指定的请求量中,允许失败的百分比。超过此百分比将触发断路器打开。 | 默认值可能因版本而异,但通常设置为50%左右。 |
5.4 Hystrix隔离机制原理
在Hystrix的源码中,隔离机制的实现主要依赖于HystrixThreadPool和HystrixSemaphore等类。
-
线程池隔离的源码实现
- 线程池的创建与管理:Hystrix通过
HystrixThreadPoolFactory
类创建和管理线程池。每个服务(或命令)的线程池通过HystrixThreadPoolKey
来标识,并存储在ConcurrentHashMap
中以便复用。 - 命令的执行:当命令(
HystrixCommand
或HystrixObservableCommand
)执行时,会首先检查对应的线程池是否有足够的资源来执行该命令。如果有,则将命令提交到线程池中异步执行;如果没有,则根据配置执行降级逻辑。(HystrixObservableCommand响应式编程实现类)。
- 线程池的创建与管理:Hystrix通过
-
信号量隔离的源码实现
- 信号量的创建与管理:Hystrix使用
HystrixSemaphore
类来实现信号量隔离。每个服务(或命令)的信号量数量通过配置指定,并在命令执行时进行检查。 - 命令的执行:在信号量隔离模式下,命令执行前会尝试获取信号量。如果成功获取,则执行命令;如果失败,则直接执行降级逻辑。
- 信号量的创建与管理:Hystrix使用
这篇关于Hystrix熔断降级组件学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!