赞
踩
Hystrix 是一个开源的 Java 库,由 Netflix 开发,用于在分布式开发中实现延迟和容错管理,以提高应用程序的弹性。Hystrix 通过使用断路器模式(Circuit Breaker Pattern)来防止分布式系统中的某个服务出现故障时,对整体系统性能造成的影响。以下是V哥在学习 Hystrix 的概念、作用和使用方法,再分析核心组件源码的详细介绍。
断路器模式(Circuit Breaker Pattern):
断路器模式是一种用于防止系统过载和灾难性故障的设计模式。在电路中,当电流超过电路的承载能力时,断路器会自动断开,防止进一步的损坏。在软件系统中,Hystrix 断路器监控服务调用的失败率,当失败率达到一定阈值时,断路器会“跳闸”,后续的调用会被快速失败,不会执行实际的服务调用,从而避免系统资源的浪费和故障的蔓延。
下面 从4个方面来解释Hystrix的作用:
防止系统雪崩:在分布式系统中,当一个服务不可用时,如果没有适当的容错机制,可能会导致大量请求堆积,进而影响其他服务,最终导致整个系统的崩溃。Hystrix 通过断路器模式,可以快速失败,避免这种情况的发生。
服务降级:当服务不可用时,Hystrix 可以提供备选方案,如返回默认值或缓存的数据,保证系统的可用性。
资源隔离:Hystrix 通过线程池和信号量来隔离资源,确保关键任务的执行不会因为其他任务的故障而受到影响。
监控和指标:Hystrix 提供了丰富的监控和度量功能,可以帮助开发者了解系统的健康状况,并进行性能调优。
在项目的 pom.xml 文件中添加 Hystrix 依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
在 Spring Boot 应用的配置类上添加 @EnableHystrix
注解。
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@EnableHystrix
public class AppConfig {
// ...
}
创建一个继承自 HystrixCommand<T>
的类,用于封装需要执行的任务。
import com.netflix.hystrix.HystrixCommand; import com.netflix.hystrix.HystrixCommandGroupKey; public class MyHystrixCommand extends HystrixCommand<String> { private static final HystrixCommandGroupKey GROUP_KEY = HystrixCommandGroupKey.Factory.asKey("MyHystrixCommandGroup"); public MyHystrixCommand() { super(Setter.withGroupKey(GROUP_KEY).andCommandKey("MyHystrixCommand")); } @Override protected String run() throws Exception { // 执行业务逻辑 return "成功执行任务"; } @Override protected String getFallback() { // 服务降级逻辑 return "服务不可用"; } }
在需要执行任务的地方,创建 HystrixCommand
的实例,并调用 execute() 方法。
public class MyService {
public String doSomething() {
MyHystrixCommand command = new MyHystrixCommand();
return command.execute();
}
}
Hystrix 与 Spring Boot Actuator 集成,可以通过 /actuator/hystrix.stream
端点来获取 Hystrix 的监控数据。
以下写的一个简单的 Spring Boot 应用,演示了如何使用 Hystrix 来增强服务的容错能力。
MyHystrixCommand.java:
import com.netflix.hystrix.HystrixCommand; import com.netflix.hystrix.HystrixCommandGroupKey; public class MyHystrixCommand extends HystrixCommand<String> { private static final HystrixCommandGroupKey GROUP_KEY = HystrixCommandGroupKey.Factory.asKey("MyHystrixCommandGroup"); public MyHystrixCommand() { super(Setter.withGroupKey(GROUP_KEY).andCommandKey("MyHystrixCommand")); } @Override protected String run() throws Exception { // 模拟业务逻辑执行 return "业务逻辑执行结果"; } @Override protected String getFallback() { // 服务降级逻辑 return "服务降级执行结果"; } }
MyService.java:
import org.springframework.stereotype.Service;
@Service
public class MyService {
public String doSomething() {
MyHystrixCommand command = new MyHystrixCommand();
return command.execute();
}
}
MyConfig.java:
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableHystrix
public class MyConfig {
// 配置类,启用 Hystrix
}
Application.java:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
在这个示例中,MyHystrixCommand
是一个自定义的 Hystrix 命令,它包含了业务逻辑的执行和失败时的回退逻辑。MyService 是一个服务类,它使用 MyHystrixCommand 来执行任务。MyConfig 是一个配置类,用于启用 Hystrix。最后,Application 是 Spring Boot 应用的入口点。
通过这种方式,你可以在 Spring Boot 应用中使用 Hystrix 来提高系统的容错能力和弹性。
由于 Hystrix 的源码较为庞大,将重点介绍几个核心类和接口,并解释它们的逻辑步骤和实现方式,这有助于你充分理解Hystrix框架。
这两个类是 Hystrix 命令模式的核心实现。HystrixCommand 用于同步执行命令,而 HystrixObservableCommand 用于异步执行。
逻辑步骤:
源码示例(简化版):
public abstract class HystrixCommand<T> extends HystrixObservableCommand<T> { protected HystrixCommand(Setter setter) { super(setter); } @Override protected Observable<T> construct() { try { return Observable.just(run()); } catch (Exception e) { return Observable.error(e); } } protected abstract T run(); protected T getFallback() { // 实现服务降级逻辑 } }
CircuitBreaker 类负责实现断路器模式的逻辑。
逻辑步骤:
源码示例(简化版):
public class CircuitBreaker { private final HystrixCommandMetrics metrics; private volatile State state; public CircuitBreaker(HystrixCommandMetrics metrics) { this.metrics = metrics; this.state = State.Closed; } public void markSuccess() { metrics.markSuccess(); transitionToOpen(); } public void markFailure() { metrics.markFailure(); transitionToOpen(); } private void transitionToOpen() { // 根据失败率决定是否跳闸 if (state == State.Closed && metrics.getHealthCounts().getErrorPercentage() > 50) { state = State.Open; } } public boolean isOpen() { return state == State.Open; } }
HystrixCommandMetrics 类负责收集命令执行的度量数据,如成功次数、失败次数等。
逻辑步骤:
源码示例(简化版):
public class HystrixCommandMetrics { private final AtomicLong successfulExecutionCount = new AtomicLong(0); private final AtomicLong failedExecutionCount = new AtomicLong(0); public void markSuccess() { successfulExecutionCount.incrementAndGet(); } public void markFailure() { failedExecutionCount.incrementAndGet(); } public int getErrorPercentage() { // 计算失败率 return (int) (failedExecutionCount.get() * 100.0 / (failedExecutionCount.get() + successfulExecutionCount.get())); } }
HystrixThreadPool 类负责管理线程池,确保每个命令在独立的线程中执行。
逻辑步骤:
源码示例(简化版):
public class HystrixThreadPool extends ThreadPoolExecutor { private final HystrixCommandMetrics metrics; public HystrixThreadPool(ThreadPoolProperties properties, HystrixCommandMetrics metrics) { super(properties); this.metrics = metrics; } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (t != null) { metrics.markFailure(); } else { metrics.markSuccess(); } } }
总结
Hystrix 通过这些核心类和接口实现了断路器模式,提供了线程池隔离、请求缓存、服务降级等功能。每个命令在执行时都会被封装为一个 HystrixCommand 实例,并在一个独立的线程池中执行。CircuitBreaker 根据 HystrixCommandMetrics 提供的度量数据来决定是否跳闸。这些组件协同工作,确保了分布式系统在面对服务故障和延迟时的健壮性和弹性。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。