目录
2.1、Hystrix 命令(HystrixCommand)
2.2、Hystrix 线程池(HystrixThreadPool)
2.3、Hystrix 熔断器(HystrixCircuitBreaker)
3.3.1、在应用程序中添加 Hystrix Dashboard 依赖包
3.3.3、在主类中启动 Hystrix Dashboard:
一、什么是 Hystrix?
官网地址:https://github.com/Netflix/Hystrix.git
我的dashboard地址:https://github.com/woyouyitouchenfeijv/Hystrix.git
1.1、Hystrix 的背景和目的
当下的微服务架构中,一个重要的问题就是服务之间的调用会产生大量的延迟和错误,从而影响整个应用程序的性能和可靠性。为了解决这个问题,Netflix公司开发了一个名为Hystrix的库,它提供了一种实现容错的机制,可以在分布式系统中帮助处理不可避免的延迟和故障。Hystrix通过使用隔离技术、断路器模式、资源池等技术,为分布式系统提供了高可用、高性能的解决方案。
1.2、Hystrix 的特点和优势
Hystrix 是一个开源的容错框架,主要应用于分布式系统中的服务熔断、服务降级、线程池隔离等方面。下面是 Hystrix 的特点和优势:
服务熔断:Hystrix 可以根据请求的失败率和请求的总数来自动熔断不可用的服务,防止服务雪崩。
服务降级:Hystrix 可以在服务不可用的情况下,通过 fallback 方法返回一个备选结果,保证系统的可用性。
线程池隔离:Hystrix 为每个服务使用一个独立的线程池来处理请求,防止因一个服务的超时或错误而影响整个应用程序的稳定性。
实时监控:Hystrix 提供了实时的监控和报告功能,可以方便地监控服务的调用情况和失败情况。
自适应控制:Hystrix 可以自适应地控制服务的流量和并发数,防止系统的负载过高。
可插拔性:Hystrix 可以与其他开源框架和技术集成,比如 Spring Cloud、Netflix Eureka 等,提供更丰富的功能和更高的性能。
二、Hystrix 的基本概念
2.1、Hystrix 命令(HystrixCommand)
它提供了丰富的服务调用控制和管理功能,使得我们可以更加方便地实现服务调用的可靠性和稳定性;是Hystrix提供的一个用于封装服务调用逻辑的类。它的主要作用是将一个服务调用请求包装成一个HystrixCommand对象,并提供以下特性:
超时控制:HystrixCommand允许设置超时时间,当服务调用时间超过指定时间时,Hystrix会中断服务调用并返回fallback响应。
熔断控制:HystrixCommand可以对服务调用进行熔断控制,当服务调用失败率超过指定阈值时,Hystrix会开启熔断保护,将服务调用请求转发到fallback逻辑,并暂时停止服务调用请求。
降级控制:HystrixCommand提供了fallback逻辑,当服务调用失败或超时时,Hystrix会自动调用fallback逻辑返回响应,避免将失败或超时的服务调用请求转发到下游服务,导致雪崩效应。
统计信息:HystrixCommand可以统计服务调用请求的成功率、响应时间、错误率等信息,方便开发人员分析服务调用请求的性能和稳定性。
请求缓存:HystrixCommand可以对服务调用请求进行缓存,避免重复的服务调用请求,提高系统性能和响应速度。
2.2、Hystrix 线程池(HystrixThreadPool)
它为每个 Hystrix 命令实例提供了一个独立的线程池来执行命令。在 Hystrix 中,命令执行的线程和命令调用的线程是分离的,因此 Hystrix 线程池的作用是为命令执行提供一个隔离的线程池。
Hystrix 线程池的配置可以通过 HystrixThreadPoolProperties 进行配置,其中包括线程池大小、队列大小、线程存活时间等参数。线程池大小决定了同时能够执行的最大命令数,如果达到了最大数目,则后续的命令将被拒绝。队列大小则是指当线程池中的所有线程都在执行命令时,新的命令将会被放入一个队列中等待执行。如果队列已满,则后续的命令将被拒绝。线程存活时间则决定了空闲线程的最长存活时间。
使用 Hystrix 线程池的好处是可以对命令进行更细粒度的隔离和控制,避免了线程池耗尽和资源争用的问题。同时,通过对线程池大小和队列大小的调整,可以在保证服务质量的前提下,提高系统的吞吐量和性能。
2.3、Hystrix 熔断器(HystrixCircuitBreaker)
用于实现熔断器模式,以保护服务调用方和被调用方之间的通信。熔断器是一种防止应用程序连锁故障的机制,当一定时间内发生某个错误或异常达到一定的阈值时,熔断器会自动跳闸,直接拒绝后续请求,并在一段时间内直接返回一个预设的错误响应,避免大量无效请求对服务的影响。
HystrixCircuitBreaker 可以监控 Hystrix 命令的执行情况,并根据一定的策略判断是否需要打开熔断器。当熔断器打开时,Hystrix 会短路请求,不再发起调用,直接返回预设的错误响应。当熔断器关闭时,Hystrix 会恢复正常调用流程。
HystrixCircuitBreaker 的实现依赖于 HystrixCommand 和 HystrixThreadPool,它会根据这两个组件的执行情况来动态地调整熔断器的状态。当 HystrixCommand 执行失败的次数超过阈值时,熔断器就会打开;当 HystrixCommand 执行成功的次数超过阈值时,熔断器就会关闭。
HystrixCircuitBreaker 提供了多种配置参数,可以用于自定义熔断器的行为。例如,我们可以设置熔断器打开时的休眠时间、错误率阈值、窗口期等等。这些参数可以通过 HystrixCommand 和 HystrixThreadPool 的注解进行配置,也可以通过配置文件进行配置。
三、Hystrix 的使用
3.1、Hystrix 的配置
3.1.1、代码配置
Hystrix 的配置非常灵活,可以根据具体的业务场景进行调整和优化,这里提供了一些配置:
-
在代码中通过 HystrixCommandProperties 或 HystrixThreadPoolProperties 等类进行配置。
-
通过注解的方式进行配置,如在需要执行的方法上使用 @HystrixCommand 注解,并在注解中设置 fallbackMethod 和 commandProperties 等属性。
-
通过在配置文件中进行配置,如在 application.properties 或 application.yml 中设置相关的属性。
3.1.2、Hystrix 配置属性介绍
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:命令执行超时时间,默认为 1000 毫秒。
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:命令执行超时时间,默认为 1000 毫秒。
hystrix.command.default.execution.timeout.enabled:是否启用命令执行超时,默认为 true。
hystrix.command.default.execution.timeout.enabled:是否启用命令执行超时,默认为 true。
hystrix.command.default.circuitBreaker.requestVolumeThreshold:断路器打开的请求阈值,默认为 20。
hystrix.command.default.circuitBreaker.errorThresholdPercentage:错误率阈值,达到该值后断路器将打开,默认为 50。
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds:断路器打开后休眠的时间,默认为 5000 毫秒。
hystrix.command.default.metrics.rollingStats.timeInMilliseconds:统计时间窗口的大小,默认为 10000 毫秒。
hystrix.threadpool.default.coreSize:线程池的核心线程数,默认为 10。
hystrix.threadpool.default.maxQueueSize:线程池队列的最大长度,默认为 -1,表示使用 SynchronousQueue。
hystrix.threadpool.default.queueSizeRejectionThreshold:队列拒绝阈值,当队列长度达到该值时,新的请求将被拒绝,默认为 5。
3.2、如何在代码中使用 Hystrix 命令
使用 HystrixCommand.Setter 对象设置了 Hystrix 命令的分组名和执行超时时间
3.2.1、定义 Hystrix 命令
可以通过继承 HystrixCommand 类并实现 run() 和 getFallback() 方法来定义 Hystrix 命令。run() 方法用于执行实际的业务逻辑,getFallback() 方法用于定义命令执行失败或超时时的回退逻辑。
public class MyHystrixCommand extends HystrixCommand<String> {
private final String name;
public MyHystrixCommand(String name) {
super(HystrixCommandGroupKey.Factory.asKey("MyHystrixCommandGroup"));
this.name = name;
}
@Override
protected String run() throws Exception {
// 实际的业务逻辑
return "Hello " + name + "!";
}
@Override
protected String getFallback() {
// 命令执行失败或超时时的回退逻辑
return "Fallback for " + name;
}
}
3.2.2、执行 Hystrix 命令
在需要执行 Hystrix 命令的地方,创建 MyHystrixCommand 实例并调用 execute() 方法即可执行 Hystrix 命令。例如:
String result = new MyHystrixCommand("World").execute();
3.2.3、Hystrix 配置
Hystrix 命令的行为可以通过配置进行调整。可以在 MyHystrixCommand 构造函数中设置 HystrixCommand.Setter 对象来配置命令的行为。例如:
public MyHystrixCommand(String name) {
super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("MyHystrixCommandGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(500)));
this.name = name;
}
3.3、如何使用 Hystrix 监控面板
创建一个 Maven 项目,并添加以下 Hystrix 依赖:
-
Hystrix-metrics-event-stream:将Hystrix的监控指标以SSE(Server-Sent Events)的方式输出到浏览器。
-
Hystrix-codahale-metrics-publisher:将Hystrix的监控指标以Dropwizard Metrics的方式输出。
-
Hystrix-dashboard:Hystrix的仪表盘,可以方便地查看Hystrix的熔断、隔离、降级等指标。
-
Hystrix-turbine:将多个Hystrix Dashboard的数据聚合在一起展示,方便集中管理。
-
Hystrix-examples:Hystrix的示例代码,包括使用Hystrix的基本用法、Hystrix Dashboard的使用、Turbine的使用等。
3.3.1、在应用程序中添加 Hystrix Dashboard 依赖包
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.18</version>
</dependency>
3.3.2、在代码中使用 @HystrixCommand
在代码中使用 @HystrixCommand
注解来标记需要容错和延迟容忍的方法,并在注解中指定 fallback 方法:
@HystrixCommand(fallbackMethod = "defaultHello")
public String hello(String name) {
// 正常业务逻辑
// ...
}
public String defaultHello(String name) {
// fallback 逻辑
// ...
}
3.3.3、在主类中启动 Hystrix Dashboard:
@SpringBootApplication
@EnableHystrixDashboard
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3.3.4、在浏览器中访问
访问 http://localhost:port/hystrix
,在界面上输入 Hystrix Stream 的 URL 地址,例如:http://localhost:port/hystrix.stream
,点击 Monitor Stream 按钮,即可看到监控面板。在监控面板中可以查看各个 Hystrix 命令的执行状况、熔断器状态、请求的流量等信息。
注意:Hystrix Dashboard 监控面板需要结合 Hystrix Stream 来使用。这里的 management
与 Spring Boot Actuator 模块相关,用来开启应用程序的监控端点。需要在 application.properties
或 application.yml
文件中添加该配置项。可以通过添加以下配置项开启 Hystrix Stream:
management.endpoints.web.exposure.include=hystrix.stream
四、Hystrix 的工作原理
4.1、线程池隔离
在Hystrix中提供了两种资源隔离策略:线程池隔离、信号量隔离。
线程池隔离:线程池隔离会为每一个依赖创建一个线程池来处理来自该依赖的请求,不同的依赖线程池相互隔离,就算依赖A出故障,导致线程池资源被耗尽,也不会影响其他依赖的线程池资源。
隔离方式 | 是否支持超时 | 是否支持熔断 | 隔离原理 | 是否异步调用 | 资源消耗 |
---|---|---|---|---|---|
线程池隔离 | 支持,可直接返回 | 支持,当线程池到达maxSize后,再请求会触发fallback接口进行熔断 | 每个服务单独用线程池,请求线程与转发处理线程不是同一个 | 可以是异步,也可以是同步。看调用的方法 | 大,大量线程的上下文切换,容易造成机器负载高 |
信号量隔离 | 不支持,如果阻塞,只能通过调用协议(如:socket超时才能返回) | 支持,当信号量达到maxConcurrentRequests后。再请求会触发fallback | 通过信号量的计数器,请求线程与转发处理线程是同一个 | 同步调用,不支持异步 | 小,只是个计数器 |
2、熔断器模式
Hystrix是一个用于分布式系统的延迟和容错库,它能够保护服务或系统在高负载或者依赖组件故障的情况下仍能继续工作。Hystrix是由Netflix公司开发的,现在是Spring Cloud的一部分。
Hystrix的核心原理是熔断器模式(Circuit Breaker Pattern)。熔断器是一种强大的容错机制,能够在遇到故障时保护应用程序免受额外的损害。在分布式系统中,如果某个服务发生故障,那么其他服务可能会受到影响,进而导致整个系统发生故障。Hystrix的熔断器模式能够在这种情况下进行保护。
Hystrix的熔断器模式通过断路器的方式实现,当某个服务的请求出现问题时,Hystrix会将该请求的结果放在断路器内部进行缓存。如果出现连续的请求失败,断路器将会切换到开路状态,此时新的请求将不再直接发给服务,而是返回一个预设的fallback结果。在一定时间内,断路器会定期地尝试重新检查该服务,如果检查成功,断路器会切换到闭合状态,否则仍然保持开路状态。
Hystrix的熔断器模式还包括一个叫做熔断器的计数器,用于记录在一个时间段内失败的请求数。当达到预设的阈值时,断路器将被打开。打开断路器后,对于该服务的请求将不再直接发送给该服务,而是直接返回fallback结果,避免对该服务产生更大的负担。在一定时间内,Hystrix会定期尝试关闭断路器,如果检测到该服务恢复正常,则断路器会关闭,否则会继续保持打开状态。
总之,Hystrix的熔断器模式能够有效保护分布式系统中的服务,防止因某个服务的故障而导致整个系统发生故障。
3、后备模式
Hystrix中的后备模式(Fallback Mode)是指当Hystrix命令执行失败或超时时,执行备用逻辑。后备逻辑应该是可靠的,并且应该能够在不同的应用程序状态下返回数据或信息。
在Hystrix中,后备逻辑由Fallback方法提供。Fallback方法是一个降级策略,当主逻辑由于某些原因而失败时,它会提供一些备用数据或逻辑。Fallback方法应该能够快速返回,因为它的目的是为了处理故障和故障恢复,而不是长时间执行复杂的操作。
Hystrix中的Fallback模式可以通过以下方式来实现:
注解方式:可以通过@HystrixCommand注解中的fallbackMethod属性来指定Fallback方法。
编程方式:可以通过HystrixCommand.Setter.withFallback()方法来指定Fallback方法。
需要注意的是,在使用Hystrix时,应该为每个HystrixCommand指定一个Fallback方法。如果没有指定Fallback方法,则在命令执行失败或超时时会抛出异常。
总的来说,后备模式可以提高系统的可靠性和稳定性。通过使用Fallback方法,可以在主逻辑出现问题时提供备用逻辑,从而确保系统的正常运行。
4、响应缓存
Hystrix提供了响应缓存来缓存对相同请求的响应,以减少对后端系统的调用次数,提高性能。在执行Hystrix命令期间,当开启了响应缓存时,会先检查缓存中是否有对应的响应,如果有则直接返回缓存中的响应,而不会再向后端系统发起请求。
响应缓存的使用需要在Hystrix命令中设置@CacheResult
注解,同时还需在HystrixCommand
中指定缓存的key。具体实现可以参考以下代码:
public class MyCommand extends HystrixCommand<String> {
private final String cacheKey;
public MyCommand(String cacheKey) {
super(HystrixCommandGroupKey.Factory.asKey("MyCommandGroup"));
this.cacheKey = cacheKey;
}
@Override
protected String run() throws Exception {
// 执行具体的业务逻辑
return "Hello World";
}
@Override
protected String getCacheKey() {
return cacheKey;
}
@Override
protected String getFallback() {
return "Fallback";
}
@Override
protected Setter getCommandProperties() {
return Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("MyCommandGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
.withCircuitBreakerEnabled(true)
.withRequestCacheEnabled(true)); // 开启响应缓存
}
@CacheResult // 设置缓存
@Override
public String execute() {
return super.execute();
}
}
在MyCommand
中,我们使用了@CacheResult
注解来开启响应缓存,并在getCacheKey()
方法中指定了缓存的key。在getCommandProperties()
方法中,我们开启了请求缓存,使得在执行Hystrix命令时,能够优先从缓存中获取响应。在执行execute()
方法时,如果缓存中有对应的响应,则直接返回缓存中的结果。否则,会执行run()
方法中的业务逻辑,并将结果缓存起来。
需要注意的是,响应缓存会占用内存空间,如果缓存中存储的数据量过大,可能会导致内存溢出。因此,需要合理设置缓存的有效期和缓存的大小,以免对系统性能造成不良影响。
五、Hystrix 的应用场景
Hystrix主要用于解决分布式系统中的容错问题,可以在系统中的不同层级中使用,包括前端、服务端、数据库层面。以下是一些 Hystrix 的应用场景:
-
服务调用:Hystrix 可以在服务调用过程中防止因依赖方错误或超时导致的服务雪崩问题。
-
数据库访问:Hystrix 可以在应用程序访问数据库时,防止因数据库连接数过多或数据库访问错误导致的应用程序崩溃问题。
-
网络资源访问:Hystrix 可以在应用程序访问外部资源时,防止因资源不可用或超时导致的应用程序崩溃问题。
-
微服务架构:在微服务架构中,服务之间的依赖关系错综复杂,Hystrix 可以在这种环境下提供容错机制,保证整个系统的稳定性。
-
大流量应用程序:在高并发的情况下,Hystrix 可以限制并发请求量,防止系统负载过高,导致服务不可用。
总之,Hystrix 适用于分布式系统中的各种容错场景,可以提供保护机制,防止应用程序出现雪崩效应,保证系统的可靠性和稳定性。