Resilience4j 完整实战教程(熔断、限流、超时、舱壁、降级)
Resilience4j 完整实战教程(熔断、限流、超时、舱壁、降级)生产可用
一、Resilience4j 是什么?
Resilience4j 是SpringCloud 轻量级容错框架,替代传统的 Hystrix,适配 SpringBoot3、云原生、微服务架构。
一句话总结:
Resilience4j 专门用来防止微服务雪崩、接口超时、第三方服务抖动、高并发打垮系统。
相比 Sentinel、Hystrix:
- 无侵入、轻量、依赖极少
- 支持 Java8+、SpringBoot3 完美适配
- 纯注解开发,不用控制台也能落地
- 生产稳定性极高,很多大厂微服务首选
二、Resilience4j 五大核心能力
- CircuitBreaker 熔断器:失败多了自动熔断,防止雪崩
- RateLimiter 限流:控制 QPS,防刷、防高并发
- TimeLimiter 超时控制:防止接口卡死、线程堆积
- Bulkhead 舱壁隔离:不同接口线程隔离,互不影响
- Retry 重试机制:瞬时失败自动重试(网络抖动必备)
三、真实生产使用场景(重点)
1. 熔断使用场景
- 调用第三方支付、物流、地图、AI 接口频繁超时
- 调用金蝶苍穹、星瀚 OpenAPI 不稳定
- 下游微服务宕机、报错率飙升
- 防止一个服务挂掉拖垮整个链路(服务雪崩)
核心逻辑:失败率高 → 熔断打开 → 直接降级,不调用下游
2. 限流使用场景
- 对外公开接口防刷、防爬虫
- 秒杀、活动接口控制 QPS
- 核心业务接口保护数据库压力
- 多用户并发请求限制
3. 超时控制场景
- 第三方接口响应慢、不确定
- 避免 Tomcat 线程池被占满导致服务卡死
- 防止大量慢查询堆积
4. 舱壁隔离场景
- 查询接口、下单接口、支付接口线程隔离
- 某个慢接口不会占满所有线程,导致其他正常接口不可用
5. 重试场景
- 网络抖动、瞬时 500、瞬时超时
- MQ 投递失败、API 瞬时波动
四、完整引入依赖(生产版本)
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
五、生产级完整配置(yml)
一套配置同时支持:熔断 + 限流 + 超时 + 舱壁 + 重试
resilience4j:
# 熔断配置
circuitbreaker:
instances:
default:
failureRateThreshold: 50 # 失败率50%熔断
slidingWindowSize: 20 # 统计最近20次请求
waitDurationInOpenState: 8000 # 熔断8秒后尝试半开
permittedNumberOfCallsInHalfOpenState: 5
# 限流配置
ratelimiter:
instances:
default:
limitForPeriod: 20 # 每秒20次请求
limitRefreshPeriod: 1s
timeoutDuration: 0
# 超时控制
timelimiter:
instances:
default:
timeoutDuration: 1.5s # 1.5秒超时
# 舱壁隔离
bulkhead:
instances:
default:
maxConcurrentCalls: 30 # 最大并发30
# 重试机制
retry:
instances:
default:
maxRetryAttempts: 2 # 最多重试2次
waitDuration: 500ms # 间隔500ms重试
六、完整可运行代码(熔断+限流+超时+降级)
生产最常用组合注解,直接复制即用。
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import io.github.resilience4j.timelimiter.annotation.TimeLimiter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
@RestController
public class ResilienceController {
/**
* 组合防护:熔断 + 限流 + 超时控制
* 适配:第三方API调用、金蝶接口、高并发查询
*/
@GetMapping("/api/query")
@CircuitBreaker(name = "default", fallbackMethod = "queryFallback")
@RateLimiter(name = "default")
@TimeLimiter(name = "default")
public CompletableFuture<String> queryData() {
return CompletableFuture.supplyAsync(() -> {
// 模拟:调用外部接口 / 金蝶苍穹API / 复杂查询
// int a = 1 / 0; // 测试熔断
// Thread.sleep(2000); // 测试超时
return "业务查询成功";
});
}
/**
* 统一降级方法
* 异常、超时、熔断、限流 都会进入这里
*/
public CompletableFuture<String> queryFallback(Exception e) {
return CompletableFuture.completedFuture(
"系统繁忙或服务异常,已触发降级保护!原因:" + e.getMessage()
);
}
}
示例二:
try {
Supplier<BatchTaskResult> decorated = () ->
retryHandler.executeWithRetry(
() -> this.executeDispatch(executor, context, definition),
taskCode
);
CircuitBreaker cb = circuitBreakerRegistry.circuitBreaker("batchTask");
decorated = CircuitBreaker.decorateSupplier(cb, decorated);
RateLimiter rl = rateLimiterRegistry.rateLimiter("batchTask");
decorated = RateLimiter.decorateSupplier(rl, decorated);
result = decorated.get();
} catch (CallNotPermittedException e) {
result = BatchTaskResult.fail("服务熔断,请稍后重试", e);
} catch (RequestNotPermitted e) {
result = BatchTaskResult.fail("请求过于频繁,请稍后重试", e);
}
CircuitBreaker cb = circuitBreakerRegistry.circuitBreaker("batchTask");从熔断器注册表获取一个名为"batchTask"的熔断器实例
执行顺序(从外到内):
decorated.get()
↓
CircuitBreaker 检查:熔断是否已打开?
│ ├── 是 → 直接抛 CallNotPermittedException(快速失败)
│ └── 否 → 继续往下
↓
coreSupplier.get()
↓
executeDispatch() ← 真正的业务逻辑
↓
成功? → CircuitBreaker 记录成功,关闭计数+1
失败? → CircuitBreaker 记录失败,失败率达到阈值 → 打开熔断器
CircuitBreaker.decorateSupplier(cb, decorated) 返回一个新的 Supplier,把它"套"在业务逻辑外面, 它内部是这样的:
// 伪代码:CircuitBreaker.decorateSupplier 做的事
() -> {
if (cb.isCallPermitted()) { // 检查熔断状态
try {
T result = decorated.get(); // 执行业务
cb.onSuccess(); // 记录成功
return result;
} catch (Exception e) {
cb.onError(e); // 记录失败
throw e;
}
} else {
throw new CallNotPermittedException("熔断中");
}
}
七、单独讲解每个组件的工作机制
1. 熔断器工作状态机
- 关闭 Closed:正常请求,统计失败率
- 打开 Open:失败率超标,直接降级,不执行业务
- 半开 HalfOpen:等待时间结束,放少量请求试探恢复
- 成功多 → 恢复 Closed,失败多 → 重新 Open
2. RateLimiter 限流原理
基于令牌桶算法,每秒重置令牌数,超出直接拒绝,性能极高。
3. TimeLimiter 超时原理
基于异步线程池执行,超时直接终止任务,避免线程卡死。
4. Bulkhead 舱壁原理
限制当前接口最大并发数,某个接口慢不会拖垮整个服务线程池。
八、Resilience4j 和 Sentinel 区别
| 对比项 | Resilience4j | Sentinel |
|---|---|---|
| 架构 | 轻量、无依赖 | 较重、需控制台 |
| 适配版本 | SpringBoot3、云原生 | 传统微服务、阿里体系 |
| 部署 | 无需额外服务 | 需部署控制台 |
| 使用方式 | 注解+配置文件 | 控制台动态规则 |
| 适用场景 | 中小型微服务、轻量化容错 | 超大流量、高并发集群 |
九、项目实战总结
在微服务项目中,我使用 Resilience4j 统一做服务容错:
对第三方接口、金蝶苍穹API、高并发查询接口统一配置熔断、限流、超时、舱壁隔离,解决了外部服务抖动导致的接口雪崩、线程堆积、超时阻塞问题,大幅提升微服务稳定性和可用性。
十、常见题总结
1. 熔断和限流的区别?
- 限流:限制 QPS,保护自己
- 熔断:下游故障触发,保护整个链路
2. 半开状态作用?
防止下游恢复后一直熔断,通过少量请求探测服务是否恢复。
3. 为什么要用 TimeLimiter?
防止外部接口无限阻塞,占满线程池导致服务宕机。
4. 舱壁模式好处?
接口之间线程隔离,互不影响,避免单点故障扩散。
(。・v・。)
喜欢这篇文章吗?欢迎分享到你的微博、QQ群,并关注我们的微博,谢谢支持。