14.3. MicroProfile Fault Tolerance
14.3.1. 概要
MicroProfile Fault Tolerance は、マイクロサービス環境においてサービスの耐障害性と回復性を実現するための機能を提供します。
14.3.2. 設定情報
MicroProfile Fault Tolerance の設定項目は、[ リファレンス > 設定 > マイクロサービスアプリケーション > MicroProfile Fault Tolerance ] を参照してください。
14.3.3. 提供機能
MicroProfile Fault Tolerance は、アプリケーションの実行論理と、実行時のエラーハンドリングを分離するための機能で、次のアノテーションを提供します。
表14.3.3-1
| 名称 |
説明 |
アノテーション名 |
| Timeout |
タイムアウトの設定、および監視を定義します。 |
@Timeout |
| Retry |
リトライ回数、間隔等のリトライ条件を設定し、再施行します。 |
@Retry |
| Fallback |
メソッドが失敗した場合に実行するクラスを定義します。 |
@Fallback |
| Bulkhead |
サービスに対する同時呼び出しの数を制限します。 |
@Bulkhead |
| CircuitBreaker |
サービスが指定の割合で失敗した場合に、指定期間内は即時例外を返却するように定義します。 |
@CircuitBreaker |
| Asynchronous |
クラスの操作を非同期にします。 |
@Asynchronous |
14.3.3.1. Timeout
タイムアウトの設定、監視を実施します。タイムアウトが発生した場合は、TimeoutExceptionをスローします。@Fallback、@CircuitBreaker、@Asynchronous、@Bulkhead、@Retryアノテーションと同時に指定することができます。
@Asynchronousの指定がない場合は、タイムアウトが発生すると、java.lang.Thread#interrupt()により割込みが発生します。ただし、次のような状況では、割込みは機能しません。
- スレッドがブロッキングI/O(DBやファイルの読み書き)でブロックされている場合や、NIOチャネルの例外発生のみを待ち受けている場合
- スレッドが待ち合わせを行っていない場合
- スレッドがInterruptedExceptionをキャッチし、割込みを無視している場合
表14.3.3.1-1
| パラメータ |
説明 |
既定値 |
| value |
タイムアウトと判断する時間を指定します。 |
1000 |
| unit |
タイムアウト時間の単位を指定します。 |
ChronoUnit.MILLIS (ミリ秒) |
14.3.3.2. Retry
リトライ回数、間隔等の設定から再施行を行います。クラスレベル、メソッドレベルでの指定が可能です。両方指定されている場合は、メソッドレベルのほうが優先されます。
@Fallback、@CircuitBreaker、@Asynchronous、@Bulkhead、@Timeoutアノテーションと同時に指定することができます。@Timeoutと同時に指定する場合、retryOnパラメータには、TimeoutExceptionや、そのスーパークラスを指定する必要があります。
表14.3.3.2-1
| パラメータ |
説明 |
既定値 |
| maxRetries |
最大リトライ回数を指定します。(-1は無限リトライを意味します) |
3 |
| delay |
遅延時間を指定します。 |
0 |
| delayUnit |
遅延時間の単位を指定します。 |
ChronoUnit.MILLIS (ミリ秒) |
| maxDuration |
最大試行時間を指定します。遅延時間より大きな値を指定します。 |
180000 |
| durationUnit |
最大試行時間の単位を指定します。 |
ChronoUnit.MILLIS (ミリ秒) |
| jitter |
ランダムにリトライ遅延時間を変えるゆらぎ値を指定します。−jitterから+jitterの範囲の値を遅延時間に加算します。 |
200 |
| jitterDelayUnit |
ゆらぎ値の単位を指定します。 |
ChronoUnit.MILLIS (ミリ秒) |
| retryOn |
リトライを行う例外を指定します。カンマで区切ることで、複数指定が可能です。 |
Exception.class |
| abortOn |
アボートさせる例外を指定します。カンマで区切ることで、複数指定が可能です。 |
指定なし |
14.3.3.3. Fallback
メソッドが失敗した場合に実行するFallbackHandlerの実装クラスや、メソッドを定義します。両方のパラメータが指定されていた場合や、fallbackMethodパラメータに指定されたメソッドが同一クラスに存在しない場合は、FaultToleranceDefinitionException例外をスローします。
@Retry、@CircuitBreaker、@Asynchronous、@Bulkhead、@Timeoutアノテーションと同時に指定することができます。BulkheadException、CircuitBreakerOpenException、TimeoutException等の例外発生もフォールバックのトリガーとなります。
表14.3.3.3-1
| パラメータ |
説明 |
既定値 |
| value |
FallbackHandlerの実装クラスを指定します。 |
DEFAULT.class |
| fallbackMethod |
同一クラス内のメソッド名を指定します。 |
指定なし |
| applyOn |
Fallbackを行う例外やエラー(java.lang.Throwableを継承するクラス)を指定します。カンマで区切ることで、複数指定が可能です。 |
Throwable.class |
| skipOn |
Fallbackを行わない例外やエラー(java.lang.Throwableを継承するクラス)を指定します。カンマで区切ることで、複数指定が可能です。 |
指定なし |
14.3.3.4. Bulkhead
サービスに対する同時呼び出しの数を制限します。
@Asynchronousアノテーションとともに利用した場合は、スレッドプール方式となり、そうでなければ、セマフォ方式となります。それ以外に、@Fallback、@CircuitBreaker、@Timeout、@Retryアノテーションと同時に指定することができます。@Fallbackが指定されていた場合は、BulkheadException例外をスローします。
表14.3.3.4-1
| パラメータ |
説明 |
既定値 |
| value |
同時に実行できるタスク数を指定します。0より大きい値を指定します。 |
10 |
| waitingTaskQueue |
待機させられるタスク数を指定します。0より大きい値を指定します。@Asynchronousアノテーションと同時に利用する場合にのみ指定できます。 |
10 |
CautionSTD
プロセスグループに配備するAP内でBulkheadアノテーションを使用する際は、プロセスグループのスレッド制御設定によるスレッド数上限が優先されます。
プロセスグループの設定値については、「
プロセスグループの設定値の説明」を参照してください。
14.3.3.5. CircuitBreaker
システムに過負荷が及ぶことを防止するために、フェイル・ファストを実行する方法を提供します。
@Timeout、@Fallback、@Asynchronous、@Bulkhead、@Retryアノテーションと同時に指定することができます。サーキットブレーカーが開くと、CircuitBreakerOpenException例外がスローされ、@Fallbackが指定されている場合は、そこで定義されたハンドラや、メソッドが実行されます。
表14.3.3.5-1
| パラメータ |
説明 |
既定値 |
| failOn |
失敗とみなす例外やエラー(java.lang.Throwableを継承するクラス)を指定します。カンマで区切ることで、複数指定が可能です。 |
Throwable.class |
| skipOn |
成功とみなす例外やエラー(java.lang.Throwableを継承するクラス)を指定します。カンマで区切ることで、複数指定が可能です。 |
指定なし |
| delay |
遅延時間を指定します。0以上の値を指定します。0は遅延なしを意味します。 |
5000 |
| delayUnit |
遅延時間の単位を指定します。 |
ChronoUnit.MILLIS |
| requestVolumeThreshold |
異常を監視する要求回数を指定します。1以上の値を指定します。 |
20 |
| failureRatio |
ブレーカーを開くトリガーとなる、監視要求回数のうちの異常発生回数の割合を指定します。0から1の間の値を指定します。 |
0.50 |
| successThreshold |
ブレーカーを閉じる連続成功回数を指定します。1以上の値を指定します。 |
1 |
サーキットブレーカには、Closed、Open、Half-openの3つの状態があり、パラメータに指定した値に従って下記の図の様に遷移します。
図14.3.3.5-1
既定値の場合、20回中10回のリクエスト送信で異常が発生した場合にブレーカーを開き、5000ミリ秒後に半開状態となってリクエスト送信を再開し、1回成功すればブレーカーを閉じます。
半開状態でリクエスト送信に失敗した場合は、再びブレーカーを開きます。
14.3.3.6. Asynchronous
クラスの操作を非同期に設定します。
アノテーションを指定するメソッドの返却値は、java.util.concurrent.CompletionStageオブジェクトかjava.util.concurrent.Futureオブジェクトである必要があります。@Timeout、@Fallback、@Bulkhead、@CircuitBreaker、@Retryアノテーションと同時に指定することができます。
表14.3.3.6-1
| パラメータ |
説明 |
既定値 |
| (パラメータ無し) |
− |
− |
14.3.3.7. ChronoUnit
MicroProfile Fault Toleranceのアノテーション用ChronoUnit定義です。
表14.3.3.7-1
| 値 |
単位 |
| DAYS |
日 |
| HOURS |
時 |
| MINUTES |
分 |
| SECONDS |
秒 |
| MILLIS |
ミリ秒 |
| NANOS |
ナノ秒 |
14.3.3.8. メトリクス情報
MicroProfile Fault Tolerance が提供するメトリクス情報です。
baseスコープに登録します。
全てのメトリクスは次の表に示すタグを付与して登録します。
各アノテーション共通のメトリクス
| 項目 |
内容 |
| 名前 |
ft.invocations.total |
| タイプ |
Counter |
| 単位 |
なし |
| 説明 |
メソッドが呼び出された回数。 |
| タグ |
- method - 完全修飾メソッド名
-
result - 結果
- valueReturned: 値を返却した
- exceptionThrown: 例外をスローした
-
fallback - Fallback適用
- applied: Fallbackを適用した
- notApplied: Fallbackを適用しなかった
- notDefined: Fallbackを定義していない
|
Retryアノテーションのメトリクス
| 項目 |
内容 |
| 名前 |
ft.retry.calls.total |
| タイプ |
Counter |
| 単位 |
なし |
| 説明 |
Retryロジックが実行された回数。メソッド呼び出しごとに1回カウントする。 |
| タグ |
- method - 完全修飾メソッド名
-
retried - リトライしたか否か
- true: リトライした
- false: リトライしなかった
-
retryResult - メソッドの最終呼び出し結果
- valueReturned: 値を返却した
- exceptionNotRetryable: リトライ対象外の例外が発生した
- maxRetriesReached: 最大リトライ回数に達した
- maxDurationReached: 最大試行時間に達した
|
| 項目 |
内容 |
| 名前 |
ft.retry.retries.total |
| タイプ |
Counter |
| 単位 |
なし |
| 説明 |
メソッドがリトライした回数。 |
| タグ |
|
Timeoutアノテーションのメトリクス
| 項目 |
内容 |
| 名前 |
ft.timeout.calls.total |
| タイプ |
Counter |
| 単位 |
なし |
| 説明 |
Timeoutロジックが実行された回数。
通常はメソッド呼び出しごとに1回カウントするが、CircuitBreakerによって
実行が遮断されるかメソッドがリトライした場合はカウントしない。 |
| タグ |
- method - 完全修飾メソッド名
-
timedOut - タイムアウトしたか否か
- true: タイムアウトした
- false: タイムアウトしなかった
|
| 項目 |
内容 |
| 名前 |
ft.timeout.executionDuration |
| タイプ |
Histogram |
| 単位 |
ナノ秒 |
| 説明 |
メソッド実行時間のヒストグラム。 |
| タグ |
|
CircuitBreakerアノテーションのメトリクス
| 項目 |
内容 |
| 名前 |
ft.circuitbreaker.calls.total |
| タイプ |
Counter |
| 単位 |
なし |
| 説明 |
CircuitBreakerロジックが実行された回数。
通常はメソッド呼び出しごとに1回カウントするが、メソッドがリトライした場合はカウントしない。 |
| タグ |
- method - 完全修飾メソッド名
-
circuitBreakerResult - failOn、skipOnによって判定されるメソッド実行結果
- success: CircuitBreakerにより実行が許可され、その後成功
- failure: CircuitBreakerにより実行が許可され、その後失敗
- circuitBreakerOpen: CircuitBreakerによって実行が遮断された
|
| 項目 |
内容 |
| 名前 |
ft.circuitbreaker.state.total |
| タイプ |
Gauge<Long> |
| 単位 |
ナノ秒 |
| 説明 |
CircuitBreakerが各状態で費やした時間。 |
| タグ |
- method - 完全修飾メソッド名
-
state - CircuitBreakerの状態
- open: Open状態
- closed: Closed状態
- halfOpen: Half-open状態
|
| 項目 |
内容 |
| 名前 |
ft.circuitbreaker.opened.total |
| タイプ |
Counter |
| 単位 |
なし |
| 説明 |
CircuitBreakerがClosed状態からOpen状態に移行した回数。 |
| タグ |
|
Bulkheadアノテーションのメトリクス
| 項目 |
内容 |
| 名前 |
ft.bulkhead.calls.total |
| タイプ |
Counter |
| 単位 |
なし |
| 説明 |
Bulkheadロジックが実行された回数。
通常はメソッド呼び出しごとに1回カウントするが、CircuitBreakerによって
実行が遮断されるかメソッドがリトライした場合はカウントしない。 |
| タグ |
- method - 完全修飾メソッド名
-
bulkheadResult - Bulkheadによるメソッド実行結果
- accepted: Bulkheadにより受理
- rejected: Bulkheadにより拒否
|
| 項目 |
内容 |
| 名前 |
ft.bulkhead.executionsRunning |
| タイプ |
Gauge<Long> |
| 単位 |
なし |
| 説明 |
現在同時実行中の数。 |
| タグ |
|
| 項目 |
内容 |
| 名前 |
ft.bulkhead.executionsWaiting |
| タイプ |
Gauge<Long> |
| 単位 |
なし |
| 説明 |
現在キューで待機している数。 |
| タグ |
|
| メモ |
Bulkheadアノテーションに加えてAsynchronousアノテーションを指定している場合のみ登録。 |
| 項目 |
内容 |
| 名前 |
ft.bulkhead.runningDuration |
| タイプ |
Histogram |
| 単位 |
ナノ秒 |
| 説明 |
メソッド実行時間のヒストグラム。 |
| タグ |
|
| 項目 |
内容 |
| 名前 |
ft.bulkhead.waitingDuration |
| タイプ |
Histogram |
| 単位 |
ナノ秒 |
| 説明 |
キューでの待機に費やした時間のヒストグラム。 |
| タグ |
|
| メモ |
Bulkheadアノテーションに加えてAsynchronousアノテーションを指定している場合のみ登録。 |
14.3.4. サンプルの実行
ここでは、MicroProfile Fault Tolerance のサンプルアプリケーションを実行する手順について、説明します。
(1) WebOTX Developer へのインポート
サンプルプロジェクトの zip ファイルを展開して、WebOTX Developer にインポートしてください。
(2) MicroProfile Fault Tolerance を利用する JAX-RS アプリケーションの作成
Fault Tolerance 関連のアノテーションを利用して、JAX-RS アプリケーションを作成します。上述のサンプルプロジェクトを確認してください。
(3) プロジェクトのビルド
WebOTX Developer のメニュー「プロジェクト」で「自動的にビルド」がチェックされていない場合は、「プロジェクトのビルド」を選択し、ビルドを行います。
(4) warファイルのエクスポート
プロジェクトを右クリックして、「エクスポート」−「WAR ファイル」を選択します。
「Destination」で出力先のパスを指定し、「終了」ボタンをクリックします。
(5) JAX-RS アプリケーションの配備
対象の環境に合わせて、アプリケーションを配備します。
コンテナ環境の場合は、[ 構築・運用 > コンテナ型仮想化 ]
を参考に、本サンプルアプリケーションを含めたコンテナイメージを作成して、コンテナを起動してください。
コンテナ環境でない場合は、[ 配備 > アプリケーション配備 > 配備・再配備・置換 > 配備・再配備 ] を参考に、配備してください。
例) エージェントプロセス上に配備する場合
otxadmin> deploy (エクスポート時に指定したWARファイル名).war
(6) JAX-RS アプリケーションの実行
ブラウザ等から、各サンプルに対するリクエストを送信します。接続先ホスト名、ポート番号は、環境に合わせて変更してください。