Hystrix 是 Spring Cloud 中实现服务熔断、降级、隔离 的核心组件,用于解决微服务架构中的雪崩效应 ,核心是快速失败、优雅降级、自动恢复 。以下从环境搭建、基础使用、高级配置、Feign 整合、监控5 个维度提供完整示例。
一、项目环境准备
1. 依赖引入(Maven)
创建 Spring Boot 项目,添加 Hystrix 及 Spring Cloud 基础依赖:
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version> <!-- 适配 Spring Cloud Hoxton.SR12 -->
</parent>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Netflix Hystrix 核心依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- 服务注册与发现(Eureka,可选,用于服务调用) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 负载均衡(RestTemplate 调用) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2. 启动类开启 Hystrix
在启动类添加 @EnableHystrix(或 @EnableCircuitBreaker)注解,开启熔断功能:
java
运行
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableHystrix // 开启 Hystrix 熔断、降级功能
public class HystrixDemoApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDemoApplication.class, args);
}
// 注册负载均衡的 RestTemplate,用于调用远程服务
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
3. 基础配置(application.yml)
yaml
server:
port: 8080 # 服务端口
spring:
application:
name: hystrix-demo # 服务名
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/ # Eureka 注册中心地址(可选)
二、基础使用:@HystrixCommand 实现熔断降级
1. 核心注解 @HystrixCommand
该注解用于标记需要 Hystrix 保护的方法,核心参数:
fallbackMethod:指定降级方法(服务失败 / 超时时执行)commandProperties:配置熔断、超时、隔离等规则groupKey:命令分组(用于线程池隔离)threadPoolKey:线程池标识(实现线程池隔离)
2. 示例 1:基础熔断降级(RestTemplate 调用)
创建服务类,模拟调用远程用户服务,配置熔断规则与降级逻辑:
java
运行
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
/**
* 调用远程用户服务,配置熔断与降级
* 熔断规则:10秒内请求数≥20,失败率≥50%,则熔断5秒
* 超时时间:3秒
*/
@HystrixCommand(
fallbackMethod = "getUserFallback", // 降级方法
commandProperties = {
// 熔断触发条件:请求数阈值
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
// 熔断触发条件:失败率阈值(百分比)
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
// 熔断后休眠时间(毫秒),休眠后进入半开状态
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),
// 执行超时时间(毫秒)
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
}
)
public String getUserById(Long userId) {
// 调用远程用户服务(user-service 为注册中心的服务名)
return restTemplate.getForObject("http://user-service/users/" + userId, String.class);
}
/**
* 降级方法:参数、返回值必须与原方法一致
* 可接收 Throwable 参数,获取异常信息
*/
public String getUserFallback(Long userId, Throwable throwable) {
return "用户服务不可用,降级返回:用户ID=" + userId + ",异常信息:" + throwable.getMessage();
}
}
3. 示例 2:多级降级(级联 Fallback)
当一级降级也可能失败时,配置多级降级:
java
运行
@Service
public class OrderService {
@HystrixCommand(fallbackMethod = "orderFallback1")
public String createOrder(Long userId, Long productId) {
// 模拟创建订单(可能失败)
if (Math.random() > 0.3) {
throw new RuntimeException("订单服务异常");
}
return "订单创建成功:用户" + userId + ",商品" + productId;
}
// 一级降级
public String orderFallback1(Long userId, Long productId, Throwable e) {
System.out.println("一级降级执行:" + e.getMessage());
// 模拟一级降级失败
if (Math.random() > 0.5) {
throw new RuntimeException("一级降级失败");
}
return "一级降级:订单创建失败,稍后重试";
}
// 二级降级(一级降级失败时执行)
@HystrixCommand(fallbackMethod = "orderFallback2")
public String orderFallback1(Long userId, Long productId) {
return "二级降级:系统繁忙,请稍后再试";
}
// 最终降级
public String orderFallback2(Long userId, Long productId) {
return "最终降级:服务不可用,请联系客服";
}
}
4. 示例 3:根据异常类型定制降级
在降级方法中通过 Throwable 判断异常类型,返回不同降级信息:
java
运行
@Service
public class PayService {
@HystrixCommand(fallbackMethod = "payFallback")
public String pay(Long orderId, Double amount) {
// 模拟不同异常
if (Math.random() > 0.7) {
throw new RuntimeException("支付服务内部错误");
} else if (Math.random() > 0.4) {
throw new java.util.concurrent.TimeoutException("支付服务超时");
}
return "支付成功:订单" + orderId + ",金额" + amount;
}
public String payFallback(Long orderId, Double amount, Throwable e) {
if (e instanceof java.util.concurrent.TimeoutException) {
return "降级:支付服务超时,请稍后重试";
} else if (e instanceof RuntimeException) {
return "降级:支付服务异常,订单" + orderId + "支付失败";
} else {
return "降级:系统繁忙,请稍后再试";
}
}
}
三、高级配置:线程池隔离与全局配置
1. 线程池隔离(核心)
Hystrix 默认使用线程池隔离,为每个服务调用分配独立线程池,避免一个服务故障耗尽所有线程。
java
运行
@Service
public class StockService {
/**
* 配置独立线程池:核心线程数5,最大线程数10,队列大小20
*/
@HystrixCommand(
fallbackMethod = "stockFallback",
threadPoolKey = "stockThreadPool", // 线程池标识
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "5"), // 核心线程数
@HystrixProperty(name = "maximumSize", value = "10"), // 最大线程数
@HystrixProperty(name = "maxQueueSize", value = "20") // 队列大小
}
)
public String deductStock(Long productId, Integer num) {
return restTemplate.getForObject("http://stock-service/stock/deduct?productId=" + productId + "&num=" + num, String.class);
}
public String stockFallback(Long productId, Integer num) {
return "库存服务降级:商品" + productId + "库存扣减失败";
}
}
2. 全局配置(application.yml)
通过配置文件统一设置 Hystrix 全局规则,避免每个方法重复配置:
yaml
hystrix:
command:
default: # 全局默认配置
circuitBreaker:
requestVolumeThreshold: 20 # 10秒内请求数≥20才判断熔断
errorThresholdPercentage: 50 # 失败率≥50%触发熔断
sleepWindowInMilliseconds: 5000 # 熔断后休眠5秒
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 # 全局超时3秒
fallback:
isolation:
semaphore:
maxConcurrentRequests: 10 # 降级方法最大并发数
threadpool:
default: # 全局线程池配置
coreSize: 10 # 核心线程数
maximumSize: 20 # 最大线程数
maxQueueSize: 50 # 队列大小
四、Feign 整合 Hystrix(微服务常用)
Spring Cloud Feign 天然支持 Hystrix,无需额外注解,只需开启配置并实现降级接口。
1. 开启 Feign Hystrix(application.yml)
yaml
feign:
hystrix:
enabled: true # 开启 Feign 整合 Hystrix
2. Feign 接口定义
java
运行
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// 指定服务名与降级类
@FeignClient(value = "user-service", fallback = UserFeignFallback.class)
public interface UserFeignClient {
@GetMapping("/users/{userId}")
String getUserById(@PathVariable("userId") Long userId);
}
3. 降级类实现
java
运行
import org.springframework.stereotype.Component;
@Component
public class UserFeignFallback implements UserFeignClient {
@Override
public String getUserById(Long userId) {
return "Feign 降级:用户服务不可用,用户ID=" + userId;
}
}
4. 使用 Feign 调用
java
运行
@Service
public class FeignUserService {
@Autowired
private UserFeignClient userFeignClient;
public String getUser(Long userId) {
return userFeignClient.getUserById(userId);
}
}
五、Hystrix 监控(Dashboard)
1. 引入监控依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2. 开启监控(启动类)
java
运行
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableHystrix
@EnableHystrixDashboard // 开启 Hystrix 监控仪表盘
public class HystrixDemoApplication {
// ... 其他代码
}
3. 暴露监控端点(application.yml)
yaml
management:
endpoints:
web:
exposure:
include: hystrix.stream # 暴露 Hystrix 监控流
4. 访问监控面板
- 启动服务,访问:
http://localhost:8080/hystrix - 在输入框填入监控流地址:
http://localhost:8080/actuator/hystrix.stream - 点击「Monitor Stream」,即可查看服务调用的熔断状态、请求数、失败率、线程池状态等实时数据。
六、核心原理总结
- 断路器状态:
-
- Closed(闭合):正常调用,统计失败率
- Open(打开):触发熔断,直接执行降级,不调用远程服务
- Half-Open(半开):熔断休眠后,允许少量请求测试服务是否恢复,成功则闭合,失败则重新打开
- 隔离机制:线程池隔离(默认)/ 信号量隔离,避免服务间相互影响
- 降级逻辑:服务失败 / 超时 / 熔断时,快速返回预设响应,提升用户体验