告别“雪崩”:构建自我保护的微服务架构

Hystrix框架概述
Hystrix对应的中文意思是”豪猪”,这种动物全身长满尖刺,能有效保护自己免受天敌伤害,形象地体现了该框架的防御机制理念。Netflix团队因此将这个框架命名为Hystrix,并采用相应的卡通形象作为logo。
在分布式系统中,服务间的依赖调用不可避免地会出现失败情况,比如超时、异常等。Hystrix的核心价值在于:当某个依赖服务出现问题时,能够保证整个系统不会因此崩溃。它提供了熔断、隔离、降级、缓存、监控等功能,确保在单个或多个依赖同时故障时系统仍然可用。
为什么需要Hystrix?
在大型分布式系统中,通常存在大量的服务依赖(HTTP、Hessian、Netty、Dubbo等),如下图所示:

在高并发场景下,这些依赖服务的稳定性对整个系统至关重要。但依赖服务存在很多不可控因素:网络延迟、资源繁忙、服务暂时不可用、服务下线等。
如下图所示:当QPS为50的依赖服务I出现故障时,其他依赖服务仍然正常:

当依赖服务I发生阻塞时,大多数服务器的线程池会出现阻塞,进而影响整个线上服务的稳定性,如下图:

在复杂的分布式架构中,应用程序依赖众多服务,这些服务在某些时刻不可避免地会发生故障。如果没有适当的隔离措施,高并发下的依赖失败很可能拖垮整个应用服务。
举例说明:一个依赖30个SOA服务的系统,每个服务可用性为99.99%。
99.99%的30次方 ≈ 99.7%
0.3%的失败率意味着一亿次请求中会有3,000,00次失败
换算成时间大约每月有2个小时服务不稳定
随着服务依赖数量的增加,服务不稳定的概率呈指数级增长
text
解决方案:对依赖服务进行隔离,Hystrix就是专门处理依赖隔离的框架,同时提供依赖服务的治理和监控功能。
Netflix公司开发并成功应用Hystrix,其使用规模如下:
The Netflix API processes 10+ billion HystrixCommand executions per day using thread isolation.
Each API instance has 40+ thread-pools with 5-20 threads in each (most are set to 10).
text
Hystrix如何实现依赖隔离?
使用命令模式HystrixCommand封装依赖调用逻辑,每个命令在独立线程或信号量控制下执行
可配置依赖调用超时时间,一般设置为比99.5%平均响应时间略高。超时后直接返回或执行降级逻辑
为每个依赖提供独立的线程池(或信号量),线程池满时立即拒绝请求,默认不采用排队,加快失败判定
依赖调用结果分为:成功、失败(异常)、超时、线程拒绝、短路。请求失败时执行降级逻辑
提供熔断器组件,可自动或手动触发,暂时停止依赖服务(默认10秒)。熔断器默认错误率阈值为50%,超过阈值自动触发
提供近实时的依赖统计和监控功能
Hystrix依赖隔离架构如下图所示:

Hystrix实战应用
Maven依赖配置:
由于源码较多,这里只展示核心测试代码:
text
public static void main(String[] args) {
System.out.println(test(“javastack”));
}
private static String test(String name) {
HystrixUtil.HystrixReqConfig hc = HystrixUtil.HystrixReqConfig.withGroupKey(“TestGroup”).withTimeout(3)
.withUnit(TimeUnit.SECONDS).withPassNum(64);
String result = HystrixUtil.getExcuteResult(new HystrixCallableService<String>() {
@Override
public String execute() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "success " + name;
}
@Override
public String fallback() {
return "fallback " + name;
}
}, hc);
return result;
}
这里设置了3秒超时触发熔断机制。
测试程序中设置5秒休眠,触发熔断器并输出:
text
fallback javastack
测试程序中设置2秒休眠,正常执行并输出:
text
success javastack
熔断器测试成功,即使某个服务出现问题,也不会影响整个系统的正常运行。
