Agent Skills by ALSEL
OpenAIソフトウェア開発⭐ リポ 0品質スコア 70/100

spring-cloud-circuitbreaker

Spring Cloud Circuit BreakerとResilience4jを使用したレジリエンスパターンについて説明します。サーキットブレーカー、リトライ、レート制限、バルクヘッド、フォールバックパターンをカバーしています。 以下の場合に使用してください:ユーザーが「circuit breaker」「resilience4j」「fallback」「retry pattern」「rate limiter」「bulkhead」「fault tolerance Spring」について言及している場合。 以下の場合は使用しないでください:基本的なHTTPエラー(コード内で処理)、Hystrix(非推奨)はResilience4jを代わりに使用してください。

description の原文を見る

Resilience patterns with Spring Cloud Circuit Breaker and Resilience4j. Covers circuit breaker, retry, rate limiter, bulkhead, and fallback patterns. USE WHEN: user mentions "circuit breaker", "resilience4j", "fallback", "retry pattern", "rate limiter", "bulkhead", "fault tolerance Spring" DO NOT USE FOR: basic HTTP errors - handle in code, Hystrix (deprecated) - use Resilience4j instead

SKILL.md 本文

Spring Cloud Circuit Breaker - クイックリファレンス

詳細情報: mcp__documentation__fetch_docs を technology: spring-cloud-circuitbreaker で使用して、包括的なドキュメントを取得してください。

依存関係

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<!-- リアクティブの場合 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>

サーキットブレーカーの状態

         ┌─────────────────────────────────────┐
         │                                     │
         ▼                                     │
    ┌─────────┐    failure threshold    ┌──────────┐
    │ CLOSED  │ ──────────────────────▶ │   OPEN   │
    │(通常)   │                         │(拒否中)   │
    └─────────┘                         └──────────┘
         ▲                                     │
         │                                     │
         │      待機時間が経過                  │
         │                                     ▼
         │                              ┌───────────┐
         └────── 成功 ──────────────────│HALF_OPEN │
                                       │ (テスト中) │
                                       └───────────┘

基本設定

application.yml

resilience4j:
  circuitbreaker:
    configs:
      default:
        sliding-window-size: 10
        sliding-window-type: COUNT_BASED
        failure-rate-threshold: 50
        slow-call-rate-threshold: 100
        slow-call-duration-threshold: 2s
        permitted-number-of-calls-in-half-open-state: 3
        wait-duration-in-open-state: 10s
        automatic-transition-from-open-to-half-open-enabled: true
        record-exceptions:
          - java.io.IOException
          - java.net.SocketTimeoutException
        ignore-exceptions:
          - com.example.BusinessException

    instances:
      user-service:
        base-config: default
        failure-rate-threshold: 30
        wait-duration-in-open-state: 5s

      payment-service:
        base-config: default
        failure-rate-threshold: 20
        slow-call-duration-threshold: 1s

  retry:
    configs:
      default:
        max-attempts: 3
        wait-duration: 500ms
        retry-exceptions:
          - java.io.IOException
        ignore-exceptions:
          - com.example.BusinessException

    instances:
      user-service:
        base-config: default
        max-attempts: 5

  timelimiter:
    configs:
      default:
        timeout-duration: 3s
        cancel-running-future: true

    instances:
      user-service:
        timeout-duration: 5s

  bulkhead:
    configs:
      default:
        max-concurrent-calls: 25
        max-wait-duration: 0

    instances:
      user-service:
        max-concurrent-calls: 10

  ratelimiter:
    configs:
      default:
        limit-for-period: 100
        limit-refresh-period: 1s
        timeout-duration: 0

    instances:
      api-calls:
        limit-for-period: 50
        limit-refresh-period: 1s

プログラマティックな使用方法

CircuitBreakerFactory

@Service
@RequiredArgsConstructor
public class UserService {

    private final CircuitBreakerFactory circuitBreakerFactory;
    private final UserClient userClient;

    public User getUser(Long id) {
        CircuitBreaker circuitBreaker = circuitBreakerFactory.create("user-service");

        return circuitBreaker.run(
            () -> userClient.getUserById(id),
            throwable -> getDefaultUser(id, throwable)
        );
    }

    private User getDefaultUser(Long id, Throwable throwable) {
        log.warn("Fallback for user {}: {}", id, throwable.getMessage());
        return User.builder()
            .id(id)
            .name("Unknown")
            .status("FALLBACK")
            .build();
    }
}

リアクティブ

@Service
public class ReactiveUserService {

    private final ReactiveCircuitBreakerFactory circuitBreakerFactory;
    private final WebClient webClient;

    public Mono<User> getUser(Long id) {
        ReactiveCircuitBreaker circuitBreaker = circuitBreakerFactory.create("user-service");

        return circuitBreaker.run(
            webClient.get()
                .uri("/users/{id}", id)
                .retrieve()
                .bodyToMono(User.class),
            throwable -> Mono.just(User.fallback(id))
        );
    }
}

アノテーションベース

@CircuitBreaker

@Service
public class PaymentService {

    @CircuitBreaker(name = "payment-service", fallbackMethod = "paymentFallback")
    public PaymentResult processPayment(PaymentRequest request) {
        return paymentClient.process(request);
    }

    private PaymentResult paymentFallback(PaymentRequest request, Throwable t) {
        log.error("Payment failed for order {}: {}", request.getOrderId(), t.getMessage());
        return PaymentResult.builder()
            .status("PENDING")
            .message("Payment service unavailable, will retry later")
            .build();
    }
}

@Retry

@Service
public class NotificationService {

    @Retry(name = "notification-service", fallbackMethod = "notifyFallback")
    public void sendNotification(Notification notification) {
        notificationClient.send(notification);
    }

    private void notifyFallback(Notification notification, Throwable t) {
        log.warn("Failed to send notification, queueing for retry: {}", t.getMessage());
        retryQueue.add(notification);
    }
}

@RateLimiter

@Service
public class ApiService {

    @RateLimiter(name = "api-calls", fallbackMethod = "rateLimitFallback")
    public ApiResponse callExternalApi(ApiRequest request) {
        return externalClient.call(request);
    }

    private ApiResponse rateLimitFallback(ApiRequest request, Throwable t) {
        throw new TooManyRequestsException("Rate limit exceeded");
    }
}

@Bulkhead

@Service
public class ReportService {

    @Bulkhead(name = "report-service", type = Bulkhead.Type.THREADPOOL)
    public CompletableFuture<Report> generateReport(ReportRequest request) {
        return CompletableFuture.supplyAsync(() -> reportGenerator.generate(request));
    }
}

@TimeLimiter

@Service
public class SlowService {

    @TimeLimiter(name = "slow-service", fallbackMethod = "timeoutFallback")
    public CompletableFuture<Result> slowOperation() {
        return CompletableFuture.supplyAsync(() -> {
            // 遅い可能性がある処理
            return performSlowOperation();
        });
    }

    private CompletableFuture<Result> timeoutFallback(Throwable t) {
        return CompletableFuture.completedFuture(Result.timeout());
    }
}

複合アノテーション

@Service
public class ResilientService {

    @CircuitBreaker(name = "backend", fallbackMethod = "fallback")
    @Retry(name = "backend")
    @RateLimiter(name = "backend")
    @Bulkhead(name = "backend")
    @TimeLimiter(name = "backend")
    public CompletableFuture<Response> resilientCall(Request request) {
        return CompletableFuture.supplyAsync(() -> backendClient.call(request));
    }

    private CompletableFuture<Response> fallback(Request request, Throwable t) {
        log.error("All resilience measures failed: {}", t.getMessage());
        return CompletableFuture.completedFuture(Response.error());
    }
}

カスタマイズ

カスタムサーキットブレーカー設定

@Configuration
public class CircuitBreakerConfig {

    @Bean
    public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() {
        return factory -> factory.configureDefault(id ->
            new Resilience4JConfigBuilder(id)
                .circuitBreakerConfig(CircuitBreakerConfig.custom()
                    .slidingWindowSize(10)
                    .failureRateThreshold(50)
                    .waitDurationInOpenState(Duration.ofSeconds(10))
                    .permittedNumberOfCallsInHalfOpenState(3)
                    .build())
                .timeLimiterConfig(TimeLimiterConfig.custom()
                    .timeoutDuration(Duration.ofSeconds(3))
                    .build())
                .build());
    }

    @Bean
    public Customizer<Resilience4JCircuitBreakerFactory> specificCustomizer() {
        return factory -> factory.configure(builder ->
            builder.circuitBreakerConfig(CircuitBreakerConfig.custom()
                .failureRateThreshold(25)
                .build()),
            "payment-service", "critical-service");
    }
}

イベントリスナー

@Component
public class CircuitBreakerEventListener {

    @Autowired
    private CircuitBreakerRegistry circuitBreakerRegistry;

    @PostConstruct
    public void init() {
        circuitBreakerRegistry.getAllCircuitBreakers().forEach(cb -> {
            cb.getEventPublisher()
                .onStateTransition(event ->
                    log.info("Circuit breaker {} state changed: {} -> {}",
                        event.getCircuitBreakerName(),
                        event.getStateTransition().getFromState(),
                        event.getStateTransition().getToState()))
                .onFailureRateExceeded(event ->
                    log.warn("Circuit breaker {} failure rate exceeded: {}%",
                        event.getCircuitBreakerName(),
                        event.getFailureRate()))
                .onSlowCallRateExceeded(event ->
                    log.warn("Circuit breaker {} slow call rate exceeded: {}%",
                        event.getCircuitBreakerName(),
                        event.getSlowCallRate()));
        });
    }
}

メトリクスとモニタリング

Actuator エンドポイント

management:
  endpoints:
    web:
      exposure:
        include: health,circuitbreakers,retries,ratelimiters,bulkheads

  health:
    circuitbreakers:
      enabled: true
    ratelimiters:
      enabled: true
# サーキットブレーカーの状態
GET /actuator/circuitbreakers

# 特定のサーキットブレーカー
GET /actuator/circuitbreakers/{name}

# サーキットブレーカーイベント
GET /actuator/circuitbreakerevents

# 詳細を含むヘルスチェック
GET /actuator/health

メトリクス(Prometheus)

management:
  metrics:
    tags:
      application: ${spring.application.name}
    export:
      prometheus:
        enabled: true

主要なメトリクス:

  • resilience4j_circuitbreaker_state
  • resilience4j_circuitbreaker_calls_total
  • resilience4j_circuitbreaker_failure_rate
  • resilience4j_retry_calls_total
  • resilience4j_ratelimiter_available_permissions
  • resilience4j_bulkhead_available_concurrent_calls

Spring Cloud Gateway との統合

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/api/users/**
          filters:
            - name: CircuitBreaker
              args:
                name: userServiceCB
                fallbackUri: forward:/fallback/users
            - name: Retry
              args:
                retries: 3
                statuses: BAD_GATEWAY,SERVICE_UNAVAILABLE

ベストプラクティス

することしないこと
適切なしきい値を設定する本番環境でデフォルトを使用する
意味のあるフォールバックを実装するフォールバックでエラーを返す
サーキットブレーカーの状態を監視する状態遷移を無視する
リソース分離にバルクヘッドを使用する1つのサービスがリソースを枯渇させる
バックオフ付きでリトライを設定する無期限にリトライする

本番環境チェックリスト

  • サービスごとにサーキットブレーカーが設定されている
  • フォールバックが意味のある応答を返す
  • メトリクスがモニタリングに公開されている
  • 状態遷移でアラートが発火する
  • 適切なタイムアウト値が設定されている
  • 指数バックオフ付きのリトライが実装されている
  • 外部 API に対するレート制限が設定されている
  • リソース分離のためのバルクヘッドが設定されている
  • ヘルスインジケータが有効になっている
  • デバッグ用にイベントがログに記録されている

このスキルを使用しない場合

  • 内部エラー - バグを修正する。サーキットブレーカーを使用しない
  • Hystrix - 廃止予定。Resilience4j を使用してください
  • データベース障害 - コネクションプール、リトライを使用してください
  • 単純なリトライ - Spring Retry で十分な場合があります

アンチパターン

アンチパターン問題解決策
すべてにサーキットブレーカーを適用オーバーヘッド、複雑さ外部/不安定な呼び出しのみに適用
フォールバックが定義されていない空の応答意味のあるフォールバックを提供する
間違ったしきい値サーキットが早期/遅期に開くSLA に基づいてチューニング
モニタリングがない問題をデバッグできないActuator メトリクスを有効にする
遅い呼び出しを無視タイムアウトが設定されないタイムアウト設定を追加する

クイックトラブルシューティング

問題診断修正
サーキットが常に開いている失敗率を確認しきい値をチューニング、根本的な問題を修正
フォールバックが呼ばれない例外の種類を確認正しい例外処理を設定
リトライが多すぎるリトライ設定を確認最大試行回数を削減
レート制限が厳しすぎるパーミッション/秒を確認リミットを増加
バルクヘッドが拒否同時呼び出しを確認最大同時実行数を増加

リファレンスドキュメント

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
d-subrahmanyam
リポジトリ
d-subrahmanyam/deno-fresh-microservices
ライセンス
MIT
最終更新
2026/3/24

Source: https://github.com/d-subrahmanyam/deno-fresh-microservices / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: d-subrahmanyam · d-subrahmanyam/deno-fresh-microservices · ライセンス: MIT