SpringCloud-Hystrix
核心价值
容错
降级 fallback
出现程序运行异常、超时等情况的时候给客户端一个友好的提示,而不是抛出异常堆栈信息或者长时间等待,从而导致服务雪崩
服务提供者使用方式
服务提供者增加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
启动类增加注解@EnableHystrix
@SpringBootApplication
@EnableHystrix
public class Application8002 {
public static void main(String[] args) {
SpringApplication.run(Application8002.class, args);
}
}
方法增加@HystrixCommand注解并新增兜底方案
@Slf4j
@Service
@RequiredArgsConstructor
@DefaultProperties(defaultFallback = "defaultHystrixHandler")
public class UserService implements IUserService {
@Override
@HystrixCommand(
fallbackMethod = "findByIdTimeOutHystrixHandler",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
}
)
public User findByIdTimeOutHystrix(Long id) {
log.debug("id={}", id);
try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {throw new RuntimeException(e);}
log.debug("sleep over"); // 熔断以后不会执行
return null;
}
@Override
@HystrixCommand
public User findByIdTimeOutHystrix2(Long id) {
log.debug("id={}", id);
try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {throw new RuntimeException(e);}
log.debug("sleep over"); // 熔断以后不会执行
return null;
}
/**
* Hystrix兜底方法
*
* @param id id
* @return {@link User}
*/
private User findByIdTimeOutHystrixHandler(Long id) {
log.error("服务端降级, id={}, ", id);
return new User();
}
/**
* Hystrix默认兜底方法
*/
private User defaultHystrixHandler() {
log.error("服务端降级 默认方法");
return User.builder().remark("😭").build();
}
@HystrixCommand中
fallbackMethod指定兜底方法,兜底方法如果入参、返回值不一致会报异常
commandProperties指定超时时间等
findByIdTimeOutHystrix方法发生异常或者超时的时候,就会调用findByIdTimeOutHystrixHandler
@DefaultProperties(defaultFallback = "defaultHystrixHandler")表示默认降级方法,如果@HystrixCommand没指定则默认用这个
findByIdTimeOutHystrix方法降级后,异常发生处后续方法不会执行
输出结果
INFO 16776 --- [nio-8002-exec-1] m.y.s.s.controller.UserController : 接收请求, id=1
DEBUG 16776 --- [x-UserService-1] m.y.s.s.service.impl.UserService : id=1
ERROR 16776 --- [ HystrixTimer-1] m.y.s.s.service.impl.UserService : 服务端降级, id=1,
可以看到执行原始方法跟兜底的方法使用的不同线程池
服务消费者使用方式
服务提供者增加依赖
启动类增加注解@EnableHystrix
配置文件开启Hystrix
feign:
hystrix:
enabled: true
定义服务的降级
@Component
@FeignClient(value = "PAYMENT-SERVICE", fallback = UserServiceFallback.class)
public interface IUserService {
@GetMapping("/provider/user/findByIdTimeOut}")
CommonResult<User> findByIdTimeOut();
}
服务消费者是在@FeignClient的fallback中指定降级类
创建降级处理类,实现服务接口IUserService
@Slf4j
@Component
public class UserServiceFallback implements IUserService {
@Override
public CommonResult<User> findByIdTimeOut() {
return CommonResult.<User>builder().code(HttpStatus.HTTP_INTERNAL_ERROR).message("客户端降级兜底").build();
}
}
熔断
拒绝访问,等检测到恢复以后才恢复
熔断状态
- Closed(闭合态):
- 默认正常状态,请求正常通过
- 持续统计失败率(默认时间窗口10秒)
- 当失败率达到阈值(默认50%)时跳转到Open状态
- Open(熔断态):
- 所有请求立即失败(快速失败)
- 经过休眠时间(默认5秒)后自动进入HalfOpen状态
- HalfOpen(半开态):
- 允许有限数量的试探请求通过
- 若请求成功率达到恢复阈值,则进入Closed状态
- 若任一请求失败,则立即返回Open状态
核心熔断配置参数
| 配置项 | 默认值 | 说明 |
|---|---|---|
circuitBreaker.enabled |
true | 是否启用熔断器 |
circuitBreaker.requestVolumeThreshold |
20 | 触发熔断的最小请求数(统计窗口内) |
circuitBreaker.errorThresholdPercentage |
50(%) | 触发熔断的失败率阈值 |
circuitBreaker.sleepWindowInMilliseconds |
5000(ms) | 熔断后的休眠时间(OPEN→HALF_OPEN) |
circuitBreaker.forceOpen |
false | 强制打开熔断器(测试用) |
circuitBreaker.forceClosed |
false | 强制关闭熔断器(忽略熔断逻辑) |
metrics.rollingStats.timeInMilliseconds |
10000(ms) | 统计窗口时长(10秒) |
全局配置方式
hystrix:
command:
default: # 全局默认配置
circuitBreaker:
enabled: true
requestVolumeThreshold: 10
errorThresholdPercentage: 40
sleepWindowInMilliseconds: 3000
execution:
isolation:
thread:
timeoutInMilliseconds: 2000
方法级配置
@Service
public class UserService {
@HystrixCommand(
fallbackMethod = "fallbackMethod",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"),
@HystrixProperty(name = "circuitBreaker.enable", value = "true"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "25")
}
)
public String riskyMethod() {
// 业务逻辑
}
private String fallbackMethod() {
return "降级响应";
}
}
限流
隔离
Hystrix的隔离策略有两种:线程隔离、信号量隔离。
THREAD(线程隔离):HystrixCommand将会在单独的线程上执行,并发请求受线程池中线程数量的限制。
SEMAPHORE(信号量隔离):HystrixCommand将会在调用线程上执行,开销相对较小,并发请求受信号量的个数的限制。
线程隔离
配置方式:
hystrix:
command:
default:
execution:
isolation:
strategy: THREAD # 显式指定线程隔离(默认)
thread:
coreSize: 10 # 线程池核心线程数(默认 10)
maxQueueSize: 100 # 线程池最大队列长度(默认 -1,无界队列)
queueSizeRejectionThreshold: 50 # 队列满时的拒绝阈值(默认 50)
keepAliveTimeMinutes: 1 # 空闲线程存活时间(分钟,默认 1)
工作原理
- 线程池分配:Hystrix 为每个命令(
HystrixCommand)或任务创建一个独立的线程池(HystrixThreadPool),线程池的大小可配置。 - 任务提交:任务被提交到线程池后,由线程池中的工作线程执行,主线程(调用方)不会阻塞。
- 超时与中断:若任务执行超时(通过
execution.isolation.thread.timeoutInMilliseconds配置),Hystrix 会中断线程并触发降级逻辑。
信号量隔离
配置方式
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE # 显式指定信号量隔离
semaphore:
maxConcurrentRequests: 20 # 最大并发请求数(默认 10)
工作原理
- 信号量控制:Hystrix 为任务分配一个信号量(计数器),初始值为配置的最大并发数(
maxConcurrentRequests)。 - 任务执行:任务在调用方线程中执行,每启动一个任务消耗一个信号量;任务完成或失败后释放信号量。
- 并发限制:当信号量耗尽时,新任务会被拒绝(触发
HystrixSemaphoreRejectedExecutionException),并直接执行降级逻辑。
监控工具
hystrix dashboard

浙公网安备 33010602011771号