mcpField
S
spring-boot-resilience4j

spring-boot-resilience4j

github.com/giuseppe-trisciuoglio开发3653.8k 次安装7 周前更新
代码仓库

关于 spring-boot-resilience4j

面向 Spring Boot 3.x 开发者的 Resilience4j 容错模式技能,涵盖配置、测试与监控。支持断路器、重试、限流、隔离、超时和回退策略。

主要功能

  1. 01断路器与回退处理
  2. 02重试及指数退避
  3. 03请求限流
  4. 04并发隔离与超时控制
  5. 05组合多种容错模式
  6. 06Actuator 监控与验证

适用场景

  1. 01保护外部服务调用免受故障影响
  2. 02应对瞬时网络错误并重试
  3. 03限制请求速率与并发负载
  4. 04验证容错状态并检查指标

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-resilience4j

安装后在 Claude Code 中输入/spring-boot-resilience4j确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
configuration-reference.md
examples.md
testing-patterns.md

详细介绍

Spring Boot Resilience4j 模式

概述

为 Spring Boot 3.x 提供 Resilience4j 模式(熔断器、重试、限流器、舱壁、超时限制器、回退),以实现容错,并提供配置和测试工作流。

适用场景

  • 实现容错并防止故障级联
  • 为服务调用添加熔断器、重试逻辑或限流
  • 通过指数退避处理瞬时故障
  • 保护服务免受过载和资源耗尽的影响
  • 组合多种模式,实现全面的弹性保护

操作说明

1. 设置和依赖项

将 Resilience4j 依赖项添加到项目中。对于 Maven,将其添加到 pom.xml:

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot3</artifactId>
    <version>2.2.0</version> // Use latest stable version
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

对于 Gradle,将其添加到 build.gradle:

implementation "io.github.resilience4j:resilience4j-spring-boot3:2.2.0"
implementation "org.springframework.boot:spring-boot-starter-aop"
implementation "org.springframework.boot:spring-boot-starter-actuator"

使用 @EnableAspectJAutoProxy 启用 AOP 注解处理(由 Spring Boot 自动配置)。

2. 熔断器模式

为调用外部服务的方法添加 @CircuitBreaker 注解:

@Service
public class PaymentService {
    private final RestTemplate restTemplate;

    public PaymentService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @CircuitBreaker(name = "paymentService", fallbackMethod = "paymentFallback")
    public PaymentResponse processPayment(PaymentRequest request) {
        return restTemplate.postForObject("http://payment-api/process",
            request, PaymentResponse.class);
    }

    private PaymentResponse paymentFallback(PaymentRequest request, Exception ex) {
        return PaymentResponse.builder()
            .status("PENDING")
            .message("Service temporarily unavailable")
            .build();
    }
}

在 application.yml 中进行配置:

resilience4j:
  circuitbreaker:
    configs:
      default:
        registerHealthIndicator: true
        slidingWindowSize: 10
        minimumNumberOfCalls: 5
        failureRateThreshold: 50
        waitDurationInOpenState: 10s
    instances:
      paymentService:
        baseConfig: default

有关完整的熔断器配置选项,请参阅 @references/configuration-reference.md。

3. 重试模式

为恢复瞬时故障的方法添加 @Retry 注解:

@Service
public class ProductService {
    private final RestTemplate restTemplate;

    public ProductService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Retry(name = "productService", fallbackMethod = "getProductFallback")
    public Product getProduct(Long productId) {
        return restTemplate.getForObject(
            "http://product-api/products/" + productId,
            Product.class);
    }

    private Product getProductFallback(Long productId, Exception ex) {
        return Product.builder()
            .id(productId)
            .name("Unavailable")
            .available(false)
            .build();
    }
}

在 application.yml 中配置重试:

resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        waitDuration: 500ms
        enableExponentialBackoff: true
        exponentialBackoffMultiplier: 2
    instances:
      productService:
        baseConfig: default
        maxAttempts: 5

有关重试异常配置,请参阅 @references/configuration-reference.md。

4. 限流器模式

添加 @RateLimiter 以控制请求速率:

@Service
public class NotificationService {
    private final EmailClient emailClient;

    public NotificationService(EmailClient emailClient) {
        this.emailClient = emailClient;
    }

    @RateLimiter(name = "notificationService",
        fallbackMethod = "rateLimitFallback")
    public void sendEmail(EmailRequest request) {
        emailClient.send(request);
    }

    private void rateLimitFallback(EmailRequest request, Exception ex) {
        throw new RateLimitExceededException(
            "Too many requests. Please try again later.");
    }
}

在 application.yml 中进行配置:

resilience4j:
  ratelimiter:
    configs:
      default:
        registerHealthIndicator: true
        limitForPeriod: 10
        limitRefreshPeriod: 1s
        timeoutDuration: 500ms
    instances:
      notificationService:
        baseConfig: default
        limitForPeriod: 5
5. 舱壁模式

添加 @Bulkhead 以隔离资源。对于同步方法,请使用 type = SEMAPHORE:

@Service
public class ReportService {
    private final ReportGenerator reportGenerator;

    public ReportService(ReportGenerator reportGenerator) {
        this.reportGenerator = reportGenerator;
    }

    @Bulkhead(name = "reportService", type = Bulkhead.Type.SEMAPHORE)
    public Report generateReport(ReportRequest request) {
        return reportGenerator.generate(request);
    }
}

对于异步/CompletableFuture 方法,请使用 type = THREADPOOL:

@Service
public class AnalyticsService {
    @Bulkhead(name = "analyticsService", type = Bulkhead.Type.THREADPOOL)
    public CompletableFuture<AnalyticsResult> runAnalytics(
            AnalyticsRequest request) {
        return CompletableFuture.supplyAsync(() ->
            analyticsEngine.analyze(request));
    }
}

在 application.yml 中进行配置:

resilience4j:
  bulkhead:
    configs:
      default:
        maxConcurrentCalls: 10
        maxWaitDuration: 100ms
    instances:
      reportService:
        baseConfig: default
        maxConcurrentCalls: 5

  thread-pool-bulkhead:
    instances:
      analyticsService:
        maxThreadPoolSize: 8
6. 超时限制器模式

为异步方法添加 @TimeLimiter,以强制执行超时边界:

@Service
public class SearchService {
    @TimeLimiter(name = "searchService", fallbackMethod = "searchFallback")
    public CompletableFuture<SearchResults> search(SearchQuery query) {
        return CompletableFuture.supplyAsync(() ->
            searchEngine.executeSearch(query));
    }

    private CompletableFuture<SearchResults> searchFallback(
            SearchQuery query, Exception ex) {
        return CompletableFuture.completedFuture(
            SearchResults.empty("Search timed out"));
    }
}

在 application.yml 中进行配置:

resilience4j:
  timelimiter:
    configs:
      default:
        timeoutDuration: 2s
        cancelRunningFuture: true
    instances:
      searchService:
        baseConfig: default
        timeoutDuration: 3s
7. 组合多种模式

在单个方法上叠加多种模式,实现全面的容错:

@Service
public class OrderService {
    @CircuitBreaker(name = "orderService")
    @Retry(name = "orderService")
    @RateLimiter(name = "orderService")
    @Bulkhead(name = "orderService")
    public Order createOrder(OrderRequest request) {
        return orderClient.createOrder(request);
    }
}

执行顺序:Retry → CircuitBreaker → RateLimiter → Bulkhead → Method

为确保一致性,所有模式都应引用同一个命名配置实例。

8. 异常处理和监控

使用 @RestControllerAdvice 创建全局异常处理器:

@RestControllerAdvice
public class ResilienceExceptionHandler {

    @ExceptionHandler(CallNotPermittedException.class)
    @ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
    public ErrorResponse handleCircuitOpen(CallNotPermittedException ex) {
        return new ErrorResponse("SERVICE_UNAVAILABLE",
            "Service currently unavailable");
    }

    @ExceptionHandler(RequestNotPermitted.class)
    @ResponseStatus(HttpStatus.TOO_MANY_REQUESTS)
    public ErrorResponse handleRateLimited(RequestNotPermitted ex) {
        return new ErrorResponse("TOO_MANY_REQUESTS",
            "Rate limit exceeded");
    }

    @ExceptionHandler(BulkheadFullException.class)
    @ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
    public ErrorResponse handleBulkheadFull(BulkheadFullException ex) {
        return new ErrorResponse("CAPACITY_EXCEEDED",
            "Service at capacity");
    }
}

在 application.yml 中启用 Actuator 端点,以监控弹性保护模式:

management:
  endpoints:
    web:
      exposure:
        include: health,metrics,circuitbreakers,retries,ratelimiters
  endpoint:
    health:
      show-details: always
  health:
    circuitbreakers:
      enabled: true
    ratelimiters:
      enabled: true

访问监控端点:

  • GET /actuator/health - 整体健康状况,包括弹性保护模式
  • GET /actuator/circuitbreakers - 熔断器状态
  • GET /actuator/metrics - 自定义弹性指标
测试与验证工作流
  1. 熔断器:使用故障调用端点 → 检查 GET /actuator/circuitbreakers 是否显示 OPEN → 等待 waitDurationInOpenState → 验证状态是否转换为 HALF_OPEN → CLOSED

  2. 重试:启用 resilience4j.retry.metrics.enabled: true → 调用端点 → 验证 retry.{instance}.successful-calls-with-retry-attempts 指标是否增加

  3. 限流器:发送超过 limitForPeriod 的请求 → 验证状态码是否为 429 → 检查 GET /actuator/ratelimiters 是否显示 LIMITED

  4. 舱壁:通过并发请求数超过 maxConcurrentCalls 进行负载测试 → 验证超出部分的请求是否立即因 BulkheadFullException 失败

  5. 超时限制器:模拟超过 timeoutDuration 的异步延迟 → 验证超时后是否触发回退

有关单元测试和集成测试策略,请参阅 @references/testing-patterns.md。

最佳实践

  • 提供回退方法:确保服务能够优雅降级,并给出有意义的响应
  • 使用指数退避:避免给恢复中的服务造成过大压力(exponentialBackoffMultiplier: 2)
  • 设置合适的阈值:将 failureRateThreshold 设置在 50-70% 之间
  • 使用构造函数注入:不要对 Resilience4j 依赖使用字段注入
  • 启用健康指示器:为所有模式设置 registerHealthIndicator: true
  • 仅重试瞬时错误:网络超时、5xx;跳过 4xx 和业务异常
  • 根据负载设置隔离舱大小:根据预期并发量计算线程池和信号量大小
  • 记录回退行为:确保回退逻辑清晰且可预测

约束和警告

  • 回退方法必须具有相同的签名,并可额外带一个异常参数
  • 熔断器状态是实例级的;在多租户场景中,确保 Bean 作用域设置正确
  • 重试操作必须是幂等的(可能会执行多次)
  • 对必须始终完成的操作不要使用熔断器;请改用超时
  • 限流器可能导致线程阻塞;请配置合适的等待时长
  • 对 POST 请求等非幂等操作使用 @Retry 时务必谨慎
  • 在高并发场景下使用线程池隔离舱时,请监控内存

示例

Before → After:熔断器
// BEFORE: No protection
public PaymentResponse processPayment(PaymentRequest request) {
    return restTemplate.postForObject("http://payment-api/process", request, PaymentResponse.class);
}

// AFTER: Circuit breaker with fallback
@CircuitBreaker(name = "paymentService", fallbackMethod = "paymentFallback")
public PaymentResponse processPayment(PaymentRequest request) {
    return restTemplate.postForObject("http://payment-api/process", request, PaymentResponse.class);
}
private PaymentResponse paymentFallback(PaymentRequest request, Exception ex) {
    return PaymentResponse.builder().status("PENDING").message("Service temporarily unavailable").build();
}
Before → After:带退避的重试
// BEFORE: Single attempt
public Order getOrder(Long orderId) {
    return orderRepository.findById(orderId).orElseThrow(() -> new OrderNotFoundException(orderId));
}

// AFTER: Retry with exponential backoff
@Retry(name = "orderService", maxAttempts = 3, waitDuration = @WaitDuration(500L), fallbackMethod = "getOrderFallback")
public Order getOrder(Long orderId) {
    return orderRepository.findById(orderId).orElseThrow(() -> new OrderNotFoundException(orderId));
}
private Order getOrderFallback(Long orderId, Exception ex) { return Order.cachedOrder(orderId); }
Before → After:限流
// BEFORE: Unbounded requests
@GetMapping("/api/data") public Data fetchData() { return dataService.process(); }

// AFTER: Rate limited
@RateLimiter(name = "dataService", fallbackMethod = "rateLimitFallback")
@GetMapping("/api/data") public Data fetchData() { return dataService.process(); }
private ResponseEntity<ErrorResponse> rateLimitFallback(Exception ex) {
    return ResponseEntity.status(429).body(new ErrorResponse("TOO_MANY_REQUESTS", "Rate limit exceeded"));
}

另请参阅: 配置参考 · 测试模式 · 示例 · Resilience4j 文档 · Actuator 技能

评论

支持 Markdown