JVMにおける耐故障性ライブラリの暫定比較


マイクロサービスを実装しているのであれば、HTTPエンドポイントを呼び出している可能性があります.HTTPの呼び出しでは、多くのことが間違って行くことができます.経験豊富な開発者は、これと幸せなパスを超えての設計を計画しています.一般に、フォールトトレランスには次の機能が含まれます.
  • 再試行
  • タイムアウト
  • サーキットブレーカ
  • フォールバック
  • サーバ側の429応答を避けるためのレートリミッタ
  • Bulkhead:同時の呼び出しの数を制限する間、レートリミッタは決定された時間枠の呼び出しの数を制限します
  • ライブラリのカップルは、これらの機能をJVMに実装します.この投稿では、MicroProfileフォールトトレランスを見ます.Failsafe とReflant 4 j.

    マイクロプロファイル故障耐性
    Microprofile Fault Tolerance MicroProfile傘プロジェクトから来ます.これは、その機能を提供するランタイムに依存する仕様であるため、2つの他とは異なります.たとえば、オープンリバティーはそのような実行時です.SmallRye Fault Tolerance もう一つ.順番に、QualkusとWildflyのような他の構成要素は、Smallryeを埋め込みました.
    MicroProfileは各機能の注釈を定義します:@Timeout , @Retry Policy , @Fallback , @Circuit Breaker , and @Bulkhead . 定義@Asynchronous .
    ランタイムは注釈を読み取りますので、複数の設定がある場合に対話する方法を理解するために注意深くドキュメントを読んでください.

    A @Fallback can be specified and it will be invoked if the TimeoutException is thrown. If @Timeout is used together with @Retry, the TimoutException will trigger the retry. When @Timeout is used with @CircuitBreaker and if a TimeoutException occurs, the failure will contribute towards the circuit open.

    -- Timeout Usage



    レジリエンス4 J
    ついてきたResilience4J 私がサーキットブレーカパターンで私の話をしていたとき.話はデモを含んでいてHystrix . ある日、最新のHystrix版にデモをアップデートしたいと思っていました.
    Reflex 4 jはいくつかのコア概念に基づいています.
  • フォールトトレランス機能あたり1つのjar、特定の統合のための追加のjar
  • 静的工場
  • 関数に適用されるデコレータパターンによる関数の構成
  • Javaの関数インタフェースとの統合Runnable , Callable , Function , など
  • 例外伝播:スローされる機能的インターフェースを使用し、ライブラリは、呼び出しパイプラインを横切ってそれを伝播させる
  • 簡単なクラス図を示しますRetry .

    各フォールトトレランス機能は、上記と同じテンプレートの周りに構築されます.一つは、関数の構成をレバレッジすることによって、いくつかの機能のパイプラインを作成することができます.
    サンプルを分析しましょう
    var retrySupplier = Retry.decorateSupplier(                                  // 1
        Retry.ofDefaults("retry"),                                               // 2
        () -> server.call()                                                      // 1
    );
    var config = new CircuitBreakerConfig.Builder()                              // 3
            .slowCallDurationThreshold(Duration.ofMillis(200))                   // 4
            .slidingWindowSize(2)                                                // 5
            .minimumNumberOfCalls(2)                                             // 6
            .build();
    var breakerSupplier = CircuitBreaker.of("circuit-breaker", config)           // 7
                                        .decorateSupplier(retrySupplier);        // 7
    supplier = SupplierUtils.recover(                                            // 8
        breakerSupplier,
        List.of(IllegalStateException.class, CallNotPermittedException.class),   // 9
        e -> "fallback"                                                         // 10
    );
    
  • 基地を飾るserver.call() 機能付きRetry : この関数は
  • デフォルトの設定
  • 新しい回路ブレーカの設定
  • 呼び出しが遅いと見なされる閾値を設定する
  • 2コールのスライドウィンドウをカウントする
  • サーキットブレーカを開くかどうかを決定する呼び出しの最小数
  • 上記の設定で回路ブレーカでリトライ機能を飾る
  • サーキットブレーカが開いているときに戻るフォールバック値を作成する
  • 取り扱う例外のリスト:彼らは伝播されません.を返しますCallNotPermittedException 回路が開いているとき.
  • 設定された例外がスローされた場合、代わりにこの関数を呼び出します
  • 機能を構成する順序は解読するのが難しい.したがって、プロジェクトはDecorators Fluent APIを使用して関数を結合するクラスです.あなたはそれを見つけることができますresilience4j-all モジュールです.上記のコードを書き換えることができます.
    var pipeline = Decorators.ofSupplier(() -> server.call())
        .withRetry(Retry.ofDefaults("retry"))
        .withCircuitBreaker(CircuitBreaker.of("circuit-breaker", config))
        .withFallback(
            List.of(IllegalStateException.class, CallNotPermittedException.class),
            e -> "fallback"
        );
    
    それは意図をより明確にする.

    フェイルセーフ
    私はずっと前にフェイルセーフにつまずいた.静的工場、関数の構成、および例外の伝播:Reserance 4 Jに似ています.
    Relaxsafe 4 Jフォールトトレランス機能はクラス階層を共有しませんが、FailSafePolicy :

    私は、Reildrin 4 Jとの主な違いがそのパイプライン化アプローチにあると思っています.Religence4 jのAPIは、最初に“基底”関数を提供し、それから任意のラッパー関数の中に埋め込む必要があります.異なる基底関数の上にパイプラインを再利用することはできません.フェイルセーフはFailsafeExecutor クラス.

    以下はパイプラインの作成方法ですFailsafeExecutor .
    ベースコールへの参照がないことに注意してください.
    var pipeline = Failsafe.with(                            // 1
        Fallback.of("fallback"),                             // 2
        Timeout.ofDuration(Duration.of(2000, MILLIS)),       // 3
        RetryPolicy.ofDefault()                              // 4
    );
    
  • 最初から最後まで適用されたポリシーの一覧を定義する
  • フォールバック値
  • 呼び出しが2000 msを超えるならばTimeoutExceededException
  • デフォルトリトライポリシー
  • この時点で、呼び出しをラップすることができます.
    pipeline.get(() -> server.call());
    
    FailSafeも流暢APIを提供します.上記のコードを書き換えることができます.
    var pipeline = Failsafe.with(Fallback.of("fallback"))
        .compose(RetryPolicy.ofDefault())
        .compose(Timeout.ofDuration(Duration.of(2000, MILLIS)));
    

    結論
    すべての3つのライブラリを多かれ少なかれ同じ機能を提供します.通常のアプリケーションサーバーやQualkusのようなCDI準拠のランタイムを使用しない場合は、MicroProfileのフォールトトレランスを忘れてください.
    FailSafeとRemove 4 Jは両方とも関数合成に基づいており、かなり似ています.もしあなたの関数パイプラインをベースコールと独立して定義する必要があるなら、フェイルセーフを好みます.それ以外の場合は、それらのいずれかを選択します.
    私はReligence 4 jに詳しいことを知っているので、おそらく私は次のプロジェクトでフェールセーフを使って経験を積むことになるでしょう.
    さらに進む
  • Microprofile Fault Tolerance specification
  • SmallRye Fault Tolerance Documentation
  • Introduction to Resilience4J
  • Failsafe overview
  • 当初公開A Java Geek 2022年(平成22年)1月7日