Java 用 Cloud クライアント ライブラリは、再試行を使用して、予期しない一時的な障害(サーバーが一時的に利用できない)を処理します。複数回試行することで、サーバーから成功レスポンスが返されることがあります。
デフォルトの再試行値は、クラウド サービスを運用するチームによって選択されます。これらの再試行値は RPC ごとに構成されます。サービスは、RPC のサブセットに対してのみ再試行を有効にできます。サービスの RPC ごとに異なる構成が設定されている可能性があります。
再試行パラメータ
クライアント ライブラリには、構成する再試行パラメータが 2 種類あります。
- 再試行ステータス コード: 再試行するステータス コードのセット。
- 再試行タイムアウトまたは試行の上限: 上限を定義する構成可能な RetrySettings 。
デフォルトの RPC 再試行構成の場所
デフォルトの再試行構成は、生成された {Client}StubSettings ファイルで定義されます。Java-Asset v3.64.0 の ExportAssets RPC を例として使用すると、デフォルトの再試行構成は次の場所に定義されます。
再試行ステータス コード:
AssetServiceStubSettings.javaファイルで構成されます。例:ImmutableMap.Builder<String, ImmutableSet<StatusCode.Code>> definitions = ImmutableMap.builder(); definitions.put("no_retry_0_codes", ImmutableSet.copyOf(Lists.<StatusCode.Code>newArrayList())); // ... More StatusCode configurations RETRYABLE_CODE_DEFINITIONS = definitions.build();再試行パラメータ:
AssetServiceStubSettings.javaファイルで構成されます。 例:ImmutableMap.Builder<String, RetrySettings> definitions = ImmutableMap.builder(); RetrySettings settings = null; settings = RetrySettings.newBuilder() .setInitialRpcTimeoutDuration(Duration.ofMillis(60000L)) .setRpcTimeoutMultiplier(1.0) .setMaxRpcTimeoutDuration(Duration.ofMillis(60000L)) .setTotalTimeoutDuration(Duration.ofMillis(60000L)) .build(); definitions.put("no_retry_0_params", settings); // ... More RetrySettings configurations RETRY_PARAM_DEFINITIONS = definitions.build();
どちらの構成も、AssetServiceStubSettings.java ファイルの RPC にマッピングされます。例:
builder
.exportAssetsSettings()
.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes"))
.setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params"));
クライアント ライブラリの再試行のコンセプト
再試行を有効にすると、RPC は複数回試行して呼び出しを成功させることができます。呼び出しが成功すると、サーバーから OK ステータス コード(gRPC から)または 2xx ステータス コード(HttpJson から)が返されます。
試行とオペレーション
次の RetrySettings 構成では、RPC の試行とオペレーションの両方の再試行設定が変更されます。
settings =
RetrySettings.newBuilder()
.setInitialRetryDelayDuration(Duration.ofMillis(100L))
.setRetryDelayMultiplier(1.3)
.setMaxRetryDelayDuration(Duration.ofMillis(60000L))
.setInitialRpcTimeoutDuration(Duration.ofMillis(60000L))
.setRpcTimeoutMultiplier(1.0)
.setMaxRpcTimeoutDuration(Duration.ofMillis(60000L))
.setTotalTimeoutDuration(Duration.ofMillis(60000L))
.build();
RPC 試行は個々の試行であり、RPC オペレーションは行われたすべての試行のコレクションです。1 回の RPC 呼び出しには、1 つのオペレーションで 1 回以上の試行が行われます。
個々の RPC の上限(試行)は、次の設定で制御されます。
setInitialRetryDelayDuration: 最初の試行までの遅延。setRetryDelayMultiplier: 各試行間に適用される遅延乗数。setMaxRetryDelayDuration: 試行で可能な最大遅延。setInitialRpcTimeoutDuration: 最初の試行のタイムアウト。setRpcTimeoutMultiplier: 各試行間に適用されるタイムアウト乗数。setMaxRpcTimeoutDuration: 試行で可能な最大タイムアウト。
RPC の合計上限(オペレーション)は、次の設定で制御されます。
setTotalTimeoutDuration: オペレーション全体で許可される合計タイムアウト。setMaxAttempts: 許可される試行の最大数。
RPC が再試行される場合
次の両方のシナリオが発生した場合、RPC は再試行されます。
- ライブラリが成功以外のステータス コードを受信し、そのステータス コードが再試行可能としてマークされている。
- RPC 呼び出しが個々の RPC の上限を超えているが、RPC の合計上限内である。
1 つのシナリオのみが true の場合、またはどちらのシナリオも true でない場合、RPC は再試行されません。
たとえば、合計タイムアウトを超えていないが、最新の試行で再試行できないステータス コードが返された場合などです。
また、RPC の上限を構成するときに、各試行の上限と RPC の合計上限を構成できます。再試行アルゴリズムにより、個々の試行の上限が RPC の合計上限内に収まるようになります。
指数バックオフ
指数バックオフでは、再試行の間隔を徐々に長くしてリクエストを再試行します。この再試行遅延値は、最大再試行遅延値で上限を設定できます。
たとえば、次の再試行構成では、次の遅延時間が発生する可能性があります。
Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms
- 試行 1: 遅延 100 ミリ秒
- 試行 2: 遅延 200 ミリ秒
- 試行 3: 遅延 400 ミリ秒
- 試行 4: 遅延 500 ミリ秒
- ...
- 試行 X: 遅延 500 ミリ秒
ジッター
ジッターは、ランダム性を使用して RPC が 呼び出されるタイミングを分散するために追加される分散です。 Google Cloud クライアントライブラリでは、再試行に対して常にジッターが 有効になっています。これにより、サーバーに過負荷をかけることなく、再試行を分散できます。
ジッターのランダム値は、再試行遅延に基づいて計算されます。各試行の前に、再試行アルゴリズムは [1, RETRY_DELAY]
の範囲でランダムな値を計算します。この計算値は、リクエストがサーバーに送信されるまでのおおよその遅延です。
次の再試行構成では、ジッターと指数バックオフを使用します。
Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms
これにより、次の遅延時間が発生する可能性があります。
- 試行 1:
[1, 100]ミリ秒の範囲でランダムな遅延 - 試行 2:
[1, 200]ミリ秒の範囲でランダムな遅延 - 試行 3:
[1, 400]ミリ秒の範囲でランダムな遅延 - 試行 4:
[1, 500]ミリ秒の範囲でランダムな遅延 - ...
- 試行 X:
[1, 500]ミリ秒の範囲でランダムな遅延
再試行の例
次の例は、再試行構成の動作を示しています。
再試行なし
この例では、再試行が無効になっています。
RetrySettings defaultNoRetrySettings =
RetrySettings.newBuilder()
// Use the default configurations for other settings
.setTotalTimeoutDuration(Duration.ofMillis(5000L))
// Explicitly set retries as disabled (maxAttempts == 1)
.setMaxAttempts(1)
.build();
または、次の例でこの動作を構成することもできます。
RetrySettings defaultNoRetrySettings =
RetrySettings.newBuilder()
.setLogicalTimeoutDuration(Duration.ofMillis(5000L))
.build();
次の表に試行を示します。
| 試行回数 | RPC タイムアウト | 再試行遅延 | 呼び出し | 呼び出し終了 |
|---|---|---|---|---|
| 1 | 5000 ミリ秒 | 0 ミリ秒 | 0 ミリ秒 | 5000 ミリ秒 |
再試行の例
この例では、指定した遅延とタイムアウトで再試行を有効にします。
RetrySettings.newBuilder()
.setInitialRetryDelayDuration(Duration.ofMillis(200L))
.setRetryDelayMultiplier(2.0)
.setMaxRetryDelayDuration(Duration.ofMillis(500L))
.setInitialRpcTimeoutDuration(Duration.ofMillis(1500L))
.setRpcTimeoutMultiplier(2.0)
.setMaxRpcTimeoutDuration(Duration.ofMillis(3000L))
.setTotalTimeoutDuration(Duration.ofMillis(5000L))
.build();
次の表に試行を示します。
| 試行回数 | RPC タイムアウト | 再試行遅延 | 呼び出し | 呼び出し終了 |
|---|---|---|---|---|
| 1 | 1500 ミリ秒 | 0 ミリ秒 | 0 ミリ秒 | 1500 ミリ秒 |
| 2(再試行) | 3000 ミリ秒 | 200 ミリ秒 | 1700 ミリ秒 | 4700 ミリ秒 |
| 3(再試行は試行されません) | - | 400 ミリ秒 | - | - |
再試行の例: 合計タイムアウトが長い
この例は最初の再試行の例と似ていますが、合計タイムアウトが長いため、追加の再試行と最後の再試行の RPC タイムアウトの上限を示しています。
RetrySettings.newBuilder()
.setInitialRetryDelayDuration(Duration.ofMillis(200L))
.setRetryDelayMultiplier(2.0)
.setMaxRetryDelayDuration(Duration.ofMillis(500L))
.setInitialRpcTimeoutDuration(Duration.ofMillis(1500L))
.setRpcTimeoutMultiplier(2.0)
.setMaxRpcTimeoutDuration(Duration.ofMillis(3000L))
.setTotalTimeoutDuration(Duration.ofMillis(10000L))
.build();
次の表に試行を示します。
| 試行回数 | RPC タイムアウト | 再試行遅延 | 呼び出し | 呼び出し終了 |
|---|---|---|---|---|
| 1 | 1500 ミリ秒 | 0 ミリ秒 | 0 ミリ秒 | 1500 ミリ秒 |
| 2(再試行) | 3000 ミリ秒 | 200 ミリ秒 | 1700 ミリ秒 | 4700 ミリ秒 |
| 3(再試行) | 4900 ミリ秒 | 400 ミリ秒 | 5100 ミリ秒 | 10000 ミリ秒 |
3 回目の再試行の RPC タイムアウト値は、合計タイムアウト値によって制限されます。 乗数(2.0)を前のタイムアウト値(3000 ミリ秒)で使用すると、RPC タイムアウトは 6000 ミリ秒になります。ただし、RPC タイムアウトは合計タイムアウトを超えてはならないため、「残り時間」(10000 - 5100 = 4900)に短縮されます。
再試行の例: RPC タイムアウトの上限
RetrySettings defaultRetrySettings =
RetrySettings.newBuilder()
.setInitialRetryDelayDuration(Duration.ofMillis(200L))
.setRetryDelayMultiplier(2.0)
.setMaxRetryDelayDuration(Duration.ofMillis(500L))
.setInitialRpcTimeoutDuration(Duration.ofMillis(500L))
.setRpcTimeoutMultiplier(2.0)
.setMaxRpcTimeoutDuration(Duration.ofMillis(2000L))
.setTotalTimeoutDuration(Duration.ofMillis(4000L))
.build();
次の表に試行を示します。
| 試行回数 | RPC タイムアウト | 再試行遅延 | 呼び出し | 呼び出し終了 |
|---|---|---|---|---|
| 1 | 500 ミリ秒 | 0 ミリ秒 | 0 ミリ秒 | 500 ミリ秒 |
| 2(再試行) | 1000 ミリ秒 | 200 ミリ秒 | 700 ミリ秒 | 1700 ミリ秒 |
| 3(再試行) | 1900 ミリ秒 | 400 ミリ秒 | 2100 ミリ秒 | 4000 ミリ秒 |
RPC タイムアウトが合計タイムアウトを超えないように上限が設定されている別の例。
RPC のカスタム再試行パラメータを構成する方法
次の例では、Java-Asset クライアント ライブラリを使用します。
カスタム構成で
RetrySettingsクラスを作成します。RetrySettings customRetrySettings = RetrySettings.newBuilder() // ... Retry Configurations .build(); RetrySettings customRetrySettings2 = RetrySettings.newBuilder() // ... Retry Configurations .build();クライアントの
StubSettings.Builderを作成し、RPC 用に構成します。AssetServiceStubSettings.Builder assetStubSettingsBuilder = AssetServiceStubSettings.newBuilder(); assetStubSettingsBuilder .exportAssetsSettings() // Set your custom Retry Settings .setRetrySettings(customRetrySettings) // Set your custom Retryable Codes .setRetryableCodes(ImmutableSet.of(StatusCode.Code.DEADLINE_EXCEEDED));提供されているコード スニペットは、
AssetServiceClientのExportAssetsRPC のカスタム再試行構成を設定しています。ExportAssetsRPC でcustomRetrySettingsで構成された再試行設定を使用するように構成し、再試行可能なコードをDEADLINE_EXCEEDEDに設定します。クライアントの設定を
assetSettingsとして作成します。AssetServiceSettings assetSettings = AssetServiceSettings.create(assetStubSettingsBuilder.build());設定を使用してクライアントを
assetClientとして作成します。try (AssetServiceClient assetClient = AssetServiceClient.create(assetSettings)) { ... }
構成する RPC ごとに手順 2 を繰り返します。次に例を示します。
AssetServiceStubSettings.Builder assetStubSettingsBuilder = AssetServiceStubSettings.newBuilder();
// Modify the retry params for ExportAssets RPC
assetStubSettingsBuilder
.exportAssetsSettings()
.setRetrySettings(customRetrySettings)
.setRetryableCodes(ImmutableSet.of(StatusCode.Code.DEADLINE_EXCEEDED));
// Modify the retry params for ListAssets RPC
assetStubSettingsBuilder
.listAssetsSettings()
.setRetrySettings(customRetrySettings2)
.setRetryableCodes(ImmutableSet.of(StatusCode.Code.UNAVAILABLE));
よくある質問
クライアントの再試行動作に関するよくある質問を以下に示します。
X 回の再試行を想定していましたが、Y 回試行されました。
最大試行回数を明示的に指定しない限り(タイムアウト構成を無効にする場合も同様)、再試行回数が常に同じになるとは限りません。RPC 遅延のジッター ランダム値により、リクエストが実際に送信されるタイミングを予測することが困難になります。
RPC は、合計タイムアウト値に達する前に失敗を返しました。
再試行アルゴリズムは、再試行ごとにジッター付きの再試行遅延値を計算します。計算された再試行遅延は、将来実行されるようにスケジュールされます(currentTime() + jitteredRetryDelay)。スケジュールされた試行時間が合計タイムアウトを超えると、最後の再試行は行われません。
カスタム設定を構成しましたが、割り当ての問題が発生しています。
RetrySettings が過度に実行されるように構成されている可能性があります。デフォルトの再試行値は、サービスを運用するチームによって選択されます。
再試行の間隔を長くして頻度を減らすために、再試行遅延(最初の再試行遅延と再試行乗数)を増やすことを検討してください。これにより、レスポンスが遅くなる可能性があります。
ユースケースによっては、より迅速なレスポンスやより頻繁な再試行が必要になる場合があります。その場合は、割り当て上限を引き上げることを検討してください。