Hystrix简介
在分布式环境下,依赖服务的失败是不可避免的。Hystrix是一个帮助你管理和这些分布式服务交互的框架,它提供了延时和故障容错机制。它提供了如下机制来提升系统的整体可靠性:1)将服务依赖的访问进行隔离;2)阻止依赖服务故障的连锁反应;3)提供容错处理策略。
Hystrix的主要目标如下:
- 对于依赖服务的失败和超时提供保护和管控机制
- 在复杂分布式系统中阻止故障的连锁反应(雪崩效应)
- 快速失败并快速恢复
- 提供失败回退机制,并在合适的场景优雅降级
- 提供准实时的监控预警和在线操作
复杂的分布式系统通常有很多依赖服务,然而每个依赖服务的复杂是不可避免的。如果宿主应用和这些依赖服务没有隔离,它就面临这被某个依赖服务拖垮的风险。在一个高流量的网站系统中,一旦某个服务出现大量延迟,宿主应用的资源会在几秒能被耗尽,进而导致服务不可用。因此这些服务依赖必须被隔离开来,以确保单个服务依赖的故障不会导致整个应用甚至整个系统的宕机。
基本原理
Hystrix通过如下策略实现服务的熔断降级:
- 所有的依赖都被封装在HystrixCommand(或HystrixObservableCommand,命令模式)中,并在隔离的线程池中运行
- 超时的调用执行的时间只会稍大与于指定的阈值(例如观测耗时的99.5%分位数)
- 为每一个依赖服务提供一个小型线程池(或信号量),如果线程池满,后续达到该服务的请求会被快速拒绝而不是排队处理
- 提供对成功、失败、超时、和线程池慢导致的请求拒绝监控
- 提供一个断路器在特定的时间对某个服务的所有请求进行中断处理,可以人工触发,或者在服务错误率达到一个指定阈值触发
- 提供请求失败的容错机制:1)拒绝;2)超时;3)熔断
- 提供准实时的监控和配置变更
如果你使用Hystrix封装所有的依赖服务,系统架构将会如下图所示。每一个依赖服务将会互相隔离并限制在独立的资源中,这些资源在失败发生时会耗尽;另外每个依赖都会具备相应的容错处理机制,该机制决定了失败发生时给上层应用怎样的响应结果。
入门示例
首先,你需要在你的应用中引入Hystrix jar包:
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.6</version>
</dependency>
下面是Hystrix的一个简单示例:
public class CommandHelloWorld extends HystrixCommand<String> {
private final String name;
public CommandHelloWorld(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected String run() {
return "Hello " + name + "!";
}
@Override
protected String getFallback() {
return "Hello Failure " + name + "!";
}
}
出于对报告和提醒的目的,group这个键用于对命令进行分组。可以通过添加getFallback()实现来达到优雅降级的目的,所有类型的故障都可以触发getFallback(),比如异常,超时,线程池(信号)拒绝和断路器短路
对于Hystrix命令可以通过execute()方法进行同步调用:
String s = new CommandHelloWorld("Bob").execute();
也可以通过queue()方法进行异步调用
Future<String> s = new CommandHelloWorld("Bob").queue();
String s = future.get();
阈值