1. 概述
本文将介绍 Resilience4j 这个轻量级容错库。
✅ 核心价值:它帮助我们在微服务或分布式系统中,优雅地处理远程调用的故障,提升系统的弹性和稳定性。
虽然它灵感来源于 Hystrix,但相比后者,Resilience4j 更现代、API 更简洁,并且模块化设计优秀。更重要的是,它不依赖于 Netflix 的技术栈,更适合当前主流的 Spring Boot 2+ 和函数式编程风格。
它提供了多个独立可插拔的模块,常见的包括:
- ✅ Circuit Breaker(熔断器):防止雪崩
- ✅ Rate Limiter(限流器):控制请求频率
- ✅ Bulkhead(舱壁):限制并发数
- ✅ Retry(重试):自动重试失败请求
- ✅ TimeLimiter(超时控制):限制调用耗时
- ✅ Cache(缓存):结果缓存
- ✅ 丰富的生态集成(Spring Boot、Retrofit 等)
每个模块都可以单独引入,按需使用,避免不必要的依赖膨胀。
2. Maven 依赖配置
使用前需引入对应模块的依赖。以 Circuit Breaker 为例:
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>2.1.0</version>
</dependency>
📌 所有模块均可在 Maven Central 查到最新版本。
后续章节将依次介绍各常用模块的使用方式。
3. 熔断器(Circuit Breaker)
需引入
resilience4j-circuitbreaker
熔断机制是防止级联故障的核心手段。当某个远程服务持续失败时,熔断器会“跳闸”,直接拒绝后续请求一段时间,避免资源被耗尽。
基本用法
先定义配置,可使用默认值或自定义:
// 使用默认配置
CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.ofDefaults();
// 或自定义配置:失败率超过 20%,且至少有 5 次调用记录时触发熔断
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(20)
.slidingWindowType(SlidingWindowType.COUNT_BASED)
.slidingWindowSize(5)
.build();
创建熔断器并装饰目标方法:
interface RemoteService {
int process(int i);
}
CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config);
CircuitBreaker circuitBreaker = registry.circuitBreaker("myService");
// 装饰函数,使其受熔断保护
Function<Integer, Integer> decorated = CircuitBreaker
.decorateFunction(circuitBreaker, service::process);
验证行为
通过测试验证熔断逻辑是否生效:
// 模拟服务始终抛异常
when(service.process(any(Integer.class))).thenThrow(new RuntimeException());
for (int i = 0; i < 10; i++) {
try {
decorated.apply(i);
} catch (Exception ignore) {}
}
// 验证:只尝试了 5 次就熔断了,后续请求被短路
verify(service, times(5)).process(any(Integer.class));
3.1 熔断器状态与关键配置
熔断器有三种状态:
状态 | 说明 |
---|---|
CLOSED |
正常状态,请求正常放行 |
OPEN |
熔断开启,所有请求直接失败(短路) |
HALF_OPEN |
半开状态,尝试放行少量请求探测服务是否恢复 |
可配置的关键参数包括:
- 🔧
failureRateThreshold
:触发熔断的失败率阈值(如 50%) - 🔧
waitDurationInOpenState
:熔断后保持 OPEN 的时间(如 30s 后进入 HALF_OPEN) - 🔧
slidingWindowSize
:滑动窗口大小,用于统计失败率 - 🔧
recordExceptions
/ignoreExceptions
:指定哪些异常计入失败 - 🎯
eventConsumer
:监听熔断事件(如日志、告警)
⚠️ 踩坑提示:默认情况下 Exception
不会被视为失败,需显式配置 recordException(Exception.class)
才能捕获。
4. 限流器(Rate Limiter)
需引入
resilience4j-ratelimiter
顾名思义,用于限制单位时间内允许的请求数量,常用于保护下游服务不被突发流量打垮。
示例代码
// 每 1 秒最多允许 2 次调用
RateLimiterConfig config = RateLimiterConfig.custom()
.limitForPeriod(2)
.limitRefreshPeriod(Duration.ofSeconds(1))
.timeoutDuration(Duration.ofMillis(100))
.build();
RateLimiterRegistry registry = RateLimiterRegistry.of(config);
RateLimiter rateLimiter = registry.rateLimiter("myRateLimiter");
Function<Integer, Integer> decorated = RateLimiter
.decorateFunction(rateLimiter, service::process);
关键配置项
limitForPeriod
:每个周期允许的请求数limitRefreshPeriod
:限流周期(如 1s)timeoutDuration
:线程等待获取许可的最大时间,超时报错eventConsumer
:可监听限流事件
✅ 简单粗暴理解:就像给接口加了个“令牌桶”,没令牌就得等或拒绝。
5. 舱壁(Bulkhead)
需引入
resilience4j-bulkhead
限制对某服务的最大并发调用数,防止某个慢接口耗尽整个应用的线程池资源。
示例:限制并发为 1
BulkheadConfig config = BulkheadConfig.custom()
.maxConcurrentCalls(1)
.maxWaitDuration(Duration.ofMillis(10))
.build();
BulkheadRegistry registry = BulkheadRegistry.of(config);
Bulkhead bulkhead = registry.bulkhead("myBulkhead");
Function<Integer, Integer> decorated = Bulkhead
.decorateFunction(bulkhead, service::process);
测试并发控制
CountDownLatch latch = new CountDownLatch(1);
// 模拟服务长时间运行
when(service.process(anyInt())).thenAnswer(invocation -> {
latch.countDown();
Thread.currentThread().join(); // 永久阻塞
return null;
});
// 提交第一个任务
ForkJoinTask<?> task = ForkJoinPool.commonPool().submit(() -> {
try {
decorated.apply(1);
} finally {
bulkhead.onComplete(); // 手动释放
}
});
latch.await(); // 等待第一个任务进入执行
// 尝试获取许可 → 应该失败(已被占用)
assertThat(bulkhead.tryAcquirePermission()).isFalse();
配置说明
maxConcurrentCalls
:最大并发数maxWaitDuration
:等待获取许可的最长时间,超时抛异常
⚠️ 注意:onComplete()
必须在 finally 中调用,否则许可不会释放!
6. 重试(Retry)
需引入
resilience4j-retry
对临时性故障(如网络抖动)自动重试,提升调用成功率。
基本用法
RetryConfig config = RetryConfig.custom()
.maxAttempts(2) // 最多重试 1 次(共 2 次尝试)
.waitDuration(Duration.ofMillis(100))
.retryExceptions(IOException.class) // 只对特定异常重试
.build();
RetryRegistry registry = RetryRegistry.of(config);
Retry retry = registry.retry("myRetry");
Function<Integer, Void> decorated = Retry.decorateFunction(retry, (Integer s) -> {
service.process(s);
return null;
});
验证重试逻辑
when(service.process(anyInt())).thenThrow(new RuntimeException());
try {
decorated.apply(1);
fail("Expected an exception after retries exhausted");
} catch (Exception e) {
// 验证:总共调用了 2 次(初始 + 1 次重试)
verify(service, times(2)).process(any(Integer.class));
}
可配置项
maxAttempts
:最大尝试次数waitDuration
:每次重试间隔intervalFunction
:可实现指数退避(如IntervalFunction.ofExponentialBackoff()
)retryExceptions
/ignoreExceptions
:控制重试触发条件
7. 缓存(Cache)
需引入
resilience4j-cache
基于 JSR-107(JCache)标准实现调用结果缓存,避免重复请求。
使用示例
javax.cache.Cache<Integer, Integer> cache = Caffeine.newBuilder()
.build(); // 实际项目可用 Caffeine、Ehcache 等
Cache<Integer, Integer> cacheContext = Cache.of(cache);
// 注意:仅支持 Supplier / Callable
Supplier<Integer> cachedSupplier = Cache.decorateSupplier(cacheContext, () -> service.process(1));
// 第一次执行真实调用,结果存入缓存
Integer result1 = cachedSupplier.get();
// 第二次直接从缓存返回
Integer result2 = cachedSupplier.get();
⚠️ 注意:该模块不提供 decorateFunction
方法,只能装饰 Supplier
或 Callable
。
8. 超时控制(TimeLimiter)
需引入
resilience4j-timelimiter
限制远程调用的执行时间,避免长时间阻塞线程。
示例:设置 1ms 超时
TimeLimiterConfig config = TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofMillis(1))
.build();
TimeLimiter timeLimiter = TimeLimiter.of(config);
验证超时行为
Future<?> futureMock = mock(Future.class);
Callable<Object> restrictedCall = TimeLimiter
.decorateFutureSupplier(timeLimiter, () -> futureMock);
restrictedCall.call();
// 验证:Future.get() 被传入了 1ms 超时参数
verify(futureMock).get(1, TimeUnit.MILLISECONDS);
与其他模块组合使用
常与 CircuitBreaker
联用,避免因超时导致熔断器误判:
Callable<Object> chainedCallable = CircuitBreaker
.decorateCallable(circuitBreaker, restrictedCall);
9. 扩展模块(Add-on Modules)
Resilience4j 提供了丰富的框架集成模块,简化配置和使用:
框架 | 模块 |
---|---|
Spring Boot | resilience4j-spring-boot2 |
Ratpack | resilience4j-ratpack |
Retrofit | resilience4j-retrofit |
Vert.x | resilience4j-vertx |
Dropwizard | resilience4j-metrics |
Prometheus | resilience4j-prometheus |
✅ 推荐:在 Spring Boot 项目中直接使用 resilience4j-spring-boot2
,可通过 YAML 配置所有策略,无需手写代码。
10. 总结
Resilience4j 是一个现代、轻量、函数式风格的容错库,相比 Hystrix 更适合当前技术栈。
📌 核心优势:
- 模块化设计,按需引入
- 函数式 API,易于组合
- 与主流框架无缝集成
- 无反射依赖,性能好
在构建高可用微服务时,合理使用 Circuit Breaker、Rate Limiter、Bulkhead 等策略,能显著提升系统稳定性。
示例代码已托管至 GitHub:https://github.com/resilience4j/resilience4j-examples