Hystrixによる分散システムの耐障害性向上とフォールバック制御

Hystrixは、Netflixが開発したオープンソースのリザイルエンスライブラリであり、分散環境下でのサービス間呼び出しにおける障害伝播を防ぎ、システム全体の安定性を担保するための重要なツールです。特に、ネットワーク不安定、依存サービスの遅延・ダウン、リソース枯渇といったリスクに対して、断路器(Circuit Breaker)、タイムアウト、フォールバック、隔離といったメカニズムを提供します。

主な機能と設計思想

  • 断路器パターンの実装:特定の依存サービスが一定回数失敗すると、以降のリクエストを即座に拒否(OPEN状態)し、一定時間後に半開(HALF_OPEN)で再試行を許可。これにより、連鎖障害や雪だるま効果を抑制します。
  • タイムアウト制御:非同期呼び出しでも明示的な実行時間制限を設定可能。デフォルトのブロッキング実行(execute())では、指定時間を超えると自動的に中止され、フォールバックへ遷移します。
  • フォールバック戦略:正常な実行が不可能な場合でも、代替応答(例:キャッシュ値、静的メッセージ、デフォルト値)を返すことで、ユーザーエクスペリエンスを維持します。
  • リソース隔離:各コマンドを独立したスレッドプールまたはセマフォで実行。あるサービスの障害が他のサービスのスレッドを占有・枯渇させることを防ぎます。
  • リアルタイムメトリクス:成功・失敗・タイムアウト・拒否・フォールバックの発生頻度など、豊富な統計情報をJSONエンドポイントやHystrix Dashboard経由で可視化できます。

コード例:カスタムHystrixCommandの実装(再構成版)

以下の実装では、元のサンプルを意図的に構造・命名・ロジックを変更し、より現実的な使用シナリオを反映しています。たとえば、外部API呼び出しを模倣し、例外処理とフォールバックの条件分岐を明確化しています。

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;

public class UserProfileFetcher extends HystrixCommand<String> {

    private final String userId;
    private final boolean simulateFailure;

    public UserProfileFetcher(String userId, boolean simulateFailure) {
        super(Setter
                .withGroupKey(HystrixCommandGroupKey.Factory.asKey("UserService"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("FetchProfile"))
                .andCommandPropertiesDefaults(
                        HystrixCommandProperties.Setter()
                                .withExecutionTimeoutInMilliseconds(800)
                                .withCircuitBreakerEnabled(true)
                                .withCircuitBreakerErrorThresholdPercentage(50)
                )
        );
        this.userId = userId;
        this.simulateFailure = simulateFailure;
    }

    @Override
    protected String run() throws Exception {
        if (simulateFailure) {
            throw new RuntimeException("Simulated external service failure");
        }
        // 実際にはHTTPクライアントなどでREST APIを呼び出す
        Thread.sleep(600);
        return String.format("{\"id\":\"%s\",\"status\":\"active\",\"role\":\"user\"}", userId);
    }

    @Override
    protected String getFallback() {
        // フォールバックでは軽量な静的データを返す
        return String.format("{\"id\":\"%s\",\"status\":\"offline\",\"role\":\"guest\"}", userId);
    }
}

実行と検証

上記コマンドは以下のように利用可能です。非同期実行(queue())もサポートしており、並列処理やタイムアウト回避に活用できます。

public class SystemOrchestrator {
    public static void main(String[] args) {
        // 成功ケース
        String successResult = new UserProfileFetcher("U123", false).execute();
        System.out.println("Success: " + successResult);

        // 失敗ケース → フォールバックが起動
        String fallbackResult = new UserProfileFetcher("U456", true).execute();
        System.out.println("Fallback: " + fallbackResult);
    }
}

監視と運用

Hystrixは/hystrix.streamエンドポイントを提供し、SSE形式でリアルタイムメトリクスを配信します。これをHystrix Dashboard(hystrix-dashboard)で可視化することで、各コマンドの成功率、レイテンシ分布、断路器状態などを一目で把握できます。Spring Cloud Netflixとの統合では、@EnableHystrixDashboardアノテーションとActuatorの組み合わせで簡単に導入可能です。

タグ: Hystrix circuit-breaker resilience4j Microservices fault-tolerance

5月23日 03:19 投稿