Hystrix 入门教程 - 基础篇之一
大纲
服务雪崩效应
服务雪崩概述
微服务之间进行 RPC 或者 HTTP 调用时,一般都会设置 调用超时、失败重试 等机制来确保服务的成功执行,这看上去很美好,但如果不考虑服务的熔断和限流,它就是造成服务雪崩的元凶。假设有两个访问量比较大的服务 A 和 B,这两个服务分别依赖 C 和 D,其中 C 和 D 服务都依赖 E 服务(如下图),这就是所谓的 扇出。A 和 B 不断地调用 C 和 D,处理客户请求和返回需要的数据;当 E 服务不能提供服务的时候,C 和 D 的 超时 和 重试机制 会被执行;由于新的请求不断的产生,会导致 C 和 D 对 E 服务的调用大量的积压,产生大量的调用等待和重试调用,会慢慢耗尽 C 和 D 的系统资源(CPU 或者内存等),然后 C 和 D 服务跟着也挂掉。A 和 B 服务会重复 C 和 D 的遭遇,导致系统资源耗尽,然后服务也挂掉了,最终整个服务都不可访问,造成了服务雪崩。

服务雪崩原因分析
- 流量突增:外部访问量突然激增,超出系统承载能力。
- 基础设施故障:硬件故障(宕机、断电、网络中断等)导致服务不可用。
- 数据库瓶颈:长事务、慢查询、SQL 超时等引发性能下降或宕机。
- 缓存失效:缓存击穿 / 雪崩,导致大量请求直接访问数据库,引发崩溃。
- 服务级联故障:
- 服务不可用:某个核心服务故障,导致依赖它的服务无法正常工作。
- 响应变慢:下游服务响应延迟,导致上游服务等待、超时、资源耗尽。
- 错误放大:下游服务出错,上游服务不断重试,加重下游服务的负担。
- 程序缺陷:Bug(内存泄漏、线程同步等待等)导致服务运行缓慢或不可用。
服务雪崩解决方案
- 隔离:通过线程池、进程池进行资源隔离,将不同类型的接口或服务独立部署,防止单个接口的故障或资源耗尽影响其他服务。
- 熔断:当检测到某个服务持续失败或响应超时率过高时,自动拒绝后续请求(快速失败),一段时间后再尝试恢复,避免问题扩散,类似电路保险丝保护。
- 降级:当服务不可用或负载过高时,提供默认数据、简化功能或关闭非核心功能,保证核心业务可用。
- 限流:对服务请求进行限速控制,当并发请求量超过阈值时直接拒绝或延迟处理,避免过多流量冲击导致服务瘫痪。
- 超时与重试:设置合理的请求超时时间,避免长时间等待;在适当情况下进行重试,防止偶发性失败影响业务。
- 监控与报警:实时监控系统指标(如响应时间、错误率、QPS),一旦异常及时告警并进行自动化处理。
熔断与降级的区别
熔断与降级的相同点:
- 最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用
- 目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃而采用的技术手段
- 粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改)
- 自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段
熔断与降级的不同点:
- 实现方式不太一样,降级具有代码侵入性 (由控制器完成或者自动降级),熔断一般称为自我熔断
- 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑
- 管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)
资源隔离的级别
- 应用级别隔离:线程池隔离、信号量隔离、连接池隔离;Hystrix 实现了前两种,其各自优缺点如下图:

- 硬件级别隔离:虚拟机、Docker、Kubernetes;比如 Docker 的资源隔离和资源限制,其通过 CGroups 来控制容器使用的资源配额,包括 CPU、内存、磁盘 I/O、网络 I/O 等。
Hystrix 介绍
Hystrix 是由 Netflix 开源的一个针对分布式系统容错处理的开源组件,2011 - 2012 年相继诞生和成熟,在 2018 年 11 月 20 日之后已经停止维护,最后一个正式版本为 1.5.18。Hystrix 单词意为 “豪猪”,浑身有刺保护自己,Hystrix 就是这样一个用来捍卫应用程序健康的利器。进一步说,Hystrix 是一个延迟和容错库,用在隔离远程系统、服务和第三方库,阻止级联故障,在复杂的分布式系统中实现恢复能力,以提高分布式系统的弹性。Hystrix 底层大量使用了 RxJava,而 Spring Cloud Hystrix 对 Hystrix 进行了二次封装,将其整合进 Spring Cloud 生态,更多介绍可参考:Hystrix 项目、Hystrix 官方英文教程、Spring Cloud Hystrix 官方中文文档
Hystrix 的设计目标
- 通过客户端库对延迟和故障进行保护和控制
- 在一个复杂的分布式系统中停止级联故障
- 快速失败和迅速恢复
- 在合理的情况下回退和优雅地降级
- 开启近实时监控、告警和操作控制
Hystrix 的核心特性
服务熔断
熔断机制是应对服务雪崩效应的一种微服务链路保护机制。日常在各种场景下都会接触到熔断这两个字,高压电路中,如果某个地方的电压过高,熔断器就会熔断,对电路进行保护。股票交易中,如果股票指数过高,也会采用熔断机制,暂停股票的交易。同样,在微服务架构中,熔断机制也是起着类似的作用。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回” 错误” 的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在 Spring Cloud 框架里熔断机制通过 Hystrix 实现,Hystrix 会监控微服务间调用的状况,当失败调用的次数达到一定阈值,缺省是 5 秒内 20 次调用失败就会启动熔断机制。服务熔断是在服务消费者(调用方)实现的,它的作用是当下游服务发生故障或响应超时时,消费者端快速失败,避免继续请求下游服务导致资源浪费和故障蔓延,Hybstrix 熔断机制的注解是 @HystrixCommand。
服务降级
服务压力剧增的时候,根据当前的业务情况及流量对一些服务和页面有策略的降级,缓解服务器的压力,以保证核心任务的进行,同时保证部分甚至大部分请求能得到正确的响应。也就是当前的请求处理不了或者出错了,给一个默认的返回结果。服务降级处理是在客户端(服务消费者)实现的,与服务端(服务提供者)没有关系。
服务降级
- 概述:
- 服务降级是指在下游服务不可用、性能下降或整体系统压力过大时,临时关闭非核心功能(服务)、提供简化 / 替代方案(如返回默认值),以保证系统核心功能正常运行。
- 目的:
- 保证系统 “核心可用”,即便牺牲部分功能。
- 常见场景:
- 商品推荐服务挂了 → 返回默认热门商品列表。
- 支付服务压力过大 → 暂时只支持余额支付,关闭第三方支付。
- 促销活动高峰期 → 暂停秒杀接口,只保留普通下单功能。
- 概述:
接口级别的降级
- 概述:
- 接口级别降级是服务降级的一种细粒度实现,仅针对特定接口进行降级处理,不影响整体服务。
- 实现方式:
- 在调用该接口时,如果检测到目标服务异常或超时,则返回默认值 / 缓存值 / 兜底数据。
- 或者直接短路该接口请求,避免资源浪费。
- 常见场景:
- 用户画像服务接口异常 → APP 首页接口降级为返回默认头像和昵称。
- 优惠券接口调用超时 → 下单接口自动忽略优惠券,正常创建订单。
- 优势:
- 更加细粒度,不会因为一个非核心接口异常就影响整个服务。
- 常用于微服务场景中,通常结合熔断一起使用(先熔断,再降级)。
- 概述:
准实时的调用监控
Hystrix 除了隔离依赖服务的调用以外,还提供了准实时的调用监控(Hystrix Dashboard)。Hystrix 会持续地记录所有通过 Hystrix 发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求、多少成功、多少失败等。Netflix 通过 hystrix-metrics-event-stream 项目实现了对以上指标的监控,而 Spring Cloud 也提供了 Hystrix Dashboard 的整合,对监控内容转化成可视化界面。
Hystrix 入门案例
1. 版本说明
在下面的的教程中,使用的 Spring Cloud 版本是 Finchley.RELEASE,对应的 Spring Boot 版本是 2.0.3,点击下载完整的案例代码
2. 创建 Maven 父级 Pom 工程
在父工程里面配置好工程需要的父级依赖,目的是为了更方便管理与简化配置,具体 Maven 配置如下:
1 | <parent> |
3. 创建 Eureka Server 工程
创建 Eureka Server 的 Maven 工程,配置工程里的 pom.xml 文件,需要引入 spring-cloud-starter-netflix-eureka-server
1 | <dependencies> |
创建 Eureka Server 的启动主类,这里添加相应注解,作为程序的入口:
1 |
|
添加 Eureka Server 需要的 application.yml 配置文件到工程中
1 | server: |
4. 创建 Provider 源服务工程
创建 Provider 的 Maven 工程,配置工程里的 pom.xml 文件,需要引入 spring-cloud-starter-netflix-hystrix、spring-cloud-starter-netflix-eureka-client
1 | <dependencies> |
创建 Provider 的启动主类,添加注解 @EnableHystrix、@EnableDiscoveryClient
1 |
|
在 application.yml 文件中指定服务名称(provider)、注册中心地址与端口号:
1 | server: |
创建用于测试的 Controller 类:
1 |
|
5. 代码测试
- 启动 Eureka Server 与 Provider 应用
- 浏览器访问
http://127.0.0.1:8080/user/getUser?userName=Jim,当用户名为Jim时会返回正确的信息 - 当用户名不为
Jim时,则会抛出运行时异常,同时 Hystrix 会降级处理返回友好的提示
Hystrix 实战应用
Feign 中使用 Hystrix
在 Feign 中,默认是自带 Hystrix 功能的,在很老的版本中默认是打开的,从最近的几个版本开始默认被关闭了,因此需要通过配置文件打开它,点击下载完整的案例代码。
在 Provider 源服务工程里,创建用于测试的 Controller 类:
1 |
|
创建 Feign Client 工程,使用 @FeignClient 定义接口,并配置降级回退类:
1 |
|
在 Feign Client 工程里,创建降级回退类,实现 FallbackFactory 接口:
1 |
|
在 Feign Client 工程里,创建启动主类:
1 |
|
在 Feign Client 工程里,创建用于测试的 Controller 类:
1 |
|
在 Feign Client 工程里,配置 pom.xml 文件,让 Feign 启用 Hystrix:
1 | server: |
测试 Feign 使用 Hystrix 的效果:
- 启动 Eureka Server、Provider 应用
- 当设置
feign.hystrix.enabled=false时,启动 Feign-Client 应用,访问http://127.0.0.1:8082/dept/get?deptName=IT,服务端返回500错误页面 - 当设置
feign.hystrix.enabled=true时,启动 Feign-Client 应用,访问http://127.0.0.1:8082/dept/get?deptName=IT,服务端返回the dept not exist in this system, please confirm deptName,这时说明 Hystrix 已经产生作用
Hystrix Dashboard
Hystrix Dashboard 仪表盘是根据系统一段时间内发生的请求情况来展示的可视化面板,这些信息是每个 HystrixCommand 执行过程中的信息,这些信息是一个指标集合和具体的系统运行情况。创建 eureka-server、provider-service、feign-client 工程,其中 provider-service 提供了一个接口返回信息。由于 Hystrix 的指标是需要端口进行支撑的,因此 provider-service 工程需要增加 actuator 依赖,并公开 hystrix.stream 端点以便能被访问到,点击下载完整的案例代码。
配置 provider-service 工程里的 pom.xml,加入以下依赖:
1 | <dependencies> |
配置 provider-service 工程里的 application.yml,当 Spring Cloud 的版本高于 Dalston 时,建议确认 management.endpoints.web.exposure.include 包含的有 hystrix.stream 或者直接为 *;否则访问 http://127.0.0.1:8080/actuator/hystrix.stream 时可能会返回 404 错误页面
1 | server: |
创建 hystrix-dashboard 工程,引入 spring-cloud-starter-netflix-hystrix-dashboard
1 | <dependencies> |
在 hystrix-dashboard 工程里,创建启动主类,添加 @EnableHystrixDashboard 注解:
1 |
|
在 hystrix-dashboard 工程里,添加 application.yml 文件
1 | server: |
测试 Hystrix Dashboard 的运行效果:
- 分别启动 eureka-server、provider-service、feign-client、hystrix-dashboard 应用
- 访问 Hystrix Dashboard 的首页:
http://127.0.0.1:8091/hystrix,查看首页截图 - 查看 provider-server 应用的监控信息:
http://127.0.0.1:8080/actuator/hystrix.stream,目前 Spring Cloud Finchley 版的 SpringBoot 版本是 2.0,所以访问路径需要加上/actuator,否则会访问不到监控页面,查看监控信息截图 - 在 Hystrix Dashboard 的首页中,填写 provider-server 应用的监控地址
http://127.0.0.1:8080/actuator/hystrix.stream,点击Monitor Stream按钮,跳转到监控图表页面,查看图表页面截图 - 调用 feigh-client 的接口:
http://127.0.0.1:8082/dept/get?deptName=IT,更换不同的deptName参数值,观察 Hystrix Dashboard 监控页面上的图表变化
Hystrix Dashboard 各项指标参数的含义:

Turbine 聚合 Hystrix
上面讲的是单个实例的 Hystrix Dashboard,但在整个系统和集群的情况下不是特别有用,所以需要一种方式来聚合整个集群下的监控状况,Turbine 就是用来聚合所有相关的 hystrix.stream 流的方案,然后在 Hystrix Dashboard 中显示,具体原理如下图:

创建 eureka-server、provider-service-user、provider-service-dept、hystrix-dashboard 工程后,再创建 hystrix-turbine 工程,用来聚合集群里的 hystrix.stream 流。为了学习方便,也可以将 hystrix-turbine 工程整合到 hystrix-dashboard 工程里,点击下载完整的案例代码。
配置 hystrix-turbine 工程里的 pom.xml 文件,由于 Turbine 依赖 Eureka 的服务注册发现,因此需要另外引入 spring-cloud-starter-netflix-eureka-client
1 | <dependencies> |
配置 hystrix-turbine 工程的 application.yml 文件:
1 | server: |
创建 hystrix-turbine 工程里的启动主类,添加 @EnableTurbine 注解后,会自动启用 Eureka Client:
1 |
|
测试 Turbine 的运行效果:
- 分别启动 eureka-server、provider-service-user、provider-service-dept 应用
- 启动 hystrix-turbine 应用,访问
http://127.0.0.1:8093/turbine.stream,观察是否能获取到集群监控信息 - 启动 hystrix-dashboard 应用,访问 Hystrix Dashboard 的首页
http://127.0.0.1:8094/hystrix,在页面上填写 hystrix-turbine 应用的监控地址http://127.0.0.1:8093/turbine.stream,然后点击Monitor Stream按钮,跳转到监控图表页面,查看图表页面截图 - 分别访问 provider-service-user 应用:
http://127.0.0.1:8092/user/getUser?userName=Jim、provider-service-dept 应用:http://127.0.0.1:8091/dept/getDept?deptName=IT,观察 Hystrix Dashboard 监控页面上的图表变化
Hystrix 扩展知识
Hystrix 的优势
Hytrix 支持异步调用,支持线程池级别的隔离
这种方式就是通过 RxJava 进行调用,等待完成后进行异步通知调用,但在 HTTP 这种请求中,主线程还是阻塞在等待请求响应结果中。带来的收益无非就是 Hytrix 能对超时进行控制。但缺点也很明显,如果是每个接口创建一个线程池的话,如果接口过多,机器中会创建大量线程,而在 Java 中,线程是属于轻量级的进程,对应是内核线程,进而造成线程的切换。而线程切换的成本也比较高。再者还需要预先给各个资源做线程池大小的分配,并且对于一些使用了 ThreadLocal 的场景不友好,因为线程切换可能导致上下文信息丢失。
Hytrix 支持百分比 + 连续错误比率的条件进行降级
这确实比 Sentinel 单纯的统计异常率,或异常数量更精细,技术选型具体根据业务去取舍。正如阿里巴巴自己比较的,Sentinel 侧重于流控,而熔断的话 Hytrix 更灵活和专业的,虽然 Hystrix 已经停止开发了,但一般情况下用 Sentinel 代替 Hytrix 也足够了。
