

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# で再試行する AWS SDK for Kotlin
<a name="retries"></a>

を呼び出すと、予期しない例外が返される AWS のサービス ことがあります。スロットリングや一時的なエラーなど、特定のタイプのエラーは、呼び出しを再試行すれば成功する場合があります。

このページでは、 が自動的に再試行 AWS SDK for Kotlin を処理する方法と、アプリケーションの再試行動作をカスタマイズする方法について説明します。

## 再試行動作について
<a name="retries-understanding"></a>

以下のセクションでは、SDK がリクエストを再試行するタイミングを決定する方法と、再試行可能と見なされる例外について説明します。

### デフォルトの再試行設定
<a name="retries-default"></a>

デフォルトでは、すべてのサービスクライアントは[標準の再試行戦略](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries/-standard-retry-strategy/index.html)で自動的に設定されます。デフォルト設定では、最大 3 回失敗する呼び出しを試行します (最初の試行と 2 回の再試行）。各呼び出し間の介入遅延は、再試行ストームを避けるために、エクスポネンシャルバックオフとランダムジッターで設定されます。この設定は、ほとんどのユースケースで機能しますが、高スループットシステムなどの状況では適さない場合があります。

SDK は、再試行可能なエラーに対してのみ再試行を試みます。再試行可能なエラーの例としては、ソケットタイムアウト、サービス側のスロットリング、同時実行または楽観的ロックの失敗、一時的なサービスエラーなどがあります。欠落または無効なパラメータ、認証/セキュリティエラー、設定ミスの例外は再試行可能とは見なされません。

最大試行回数、遅延とバックオフ、トークンバケットの設定を設定することで、標準の再試行戦略をカスタマイズできます。

### どの例外を再試行できますか?
<a name="retries-default-policy-details"></a>

は、再試行可能な例外を決定する事前設定された再試行ポリシー AWS SDK for Kotlin を使用します。サービスクライアント設定には、再試行に適用されるポリシーを指定する`retryPolicy`プロパティがあります。カスタム値を指定しない場合、デフォルト値は [AwsRetryPolicy](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/aws-http/aws.sdk.kotlin.runtime.http.retries/-aws-retry-policy/) です。

以下の例外は、 によって再試行可能であると判断されます`AwsRetryPolicy`。

#### エラーコードで再試行可能
<a name="retries-retryable-by-error-code"></a>

`sdkErrorMetadata.errorCode` 以下の `ServiceException`を持つ :
+ `BandwidthLimitExceeded`
+ `EC2ThrottledException`
+ `IDPCommunicationError`
+ `LimitExceededException`
+ `PriorRequestNotComplete`
+ `ProvisionedThroughputExceededException`
+ `RequestLimitExceeded`
+ `RequestThrottled`
+ `RequestThrottledException`
+ `RequestTimeout`
+ `RequestTimeoutException`
+ `SlowDown`
+ `ThrottledException`
+ `Throttling`
+ `ThrottlingException`
+ `TooManyRequestsException`
+ `TransactionInProgressException`

#### HTTP ステータスコードで再試行可能
<a name="retries-retryable-by-status-code"></a>

`sdkErrorMetadata.statusCode` 以下の `ServiceException`を持つ :
+ 500 (内部サービスエラー)
+ 502 (不正なゲートウェイ)
+ 503 (サービス利用不可)
+ 504 (ゲートウェイタイムアウト)

#### エラータイプで再試行可能
<a name="retries-retryable-by-error-type"></a>

`sdkErrorMetadata.errorType` 以下の `ServiceException`を持つ :
+ `ErrorType.Server` (内部サービスエラーなど)
+ `ErrorType.Client` (無効なリクエスト、リソースが見つからない、アクセスが拒否されたなど)

#### SDK メタデータで再試行可能
<a name="retries-retryable-by-metadata"></a>

以下の`SdkBaseException`場合:
+ `sdkErrorMetadata.isRetryable` は `true` (クライアント側のタイムアウト、ネットワーク/ソケットエラーなど)
+ `sdkErrorMetadata.isThrottling` は `true` (短時間にリクエストが多すぎるなど)

各サービスクライアントによってスローされる可能性のある例外の完全なリストについては、[サービス固有の API リファレンスドキュメント](https://docs.aws.amazon.com/#products)を参照してください。

### 例外が再試行可能かどうかを確認します。
<a name="retries-check-exception-retryable"></a>

SDK が例外を再試行可能と見なすかどうかを判断するには、キャッチされた例外の `isRetryable`プロパティを確認します。

```
try {
    dynamoDbClient.putItem {
        tableName = "MyTable"
        item = mapOf("id" to AttributeValue.S("123"))
    }
} catch (e: SdkBaseException) {
    println("Exception occurred: ${e.message}")
    
    if (e.sdkErrorMetadata.isRetryable) {
        println("This exception is retryable - SDK will automatically retry")
        println("If you're seeing this, retries may have been exhausted")
    } else {
        println("This exception is not retryable - fix the underlying issue")
        
        // Common non-retryable scenarios.
        when {
            e.message?.contains("ValidationException") == true -> 
                println("Check your request parameters")
            e.message?.contains("AccessDenied") == true -> 
                println("Check your IAM permissions")
            e.message?.contains("ResourceNotFound") == true -> 
                println("Verify the resource exists")
        }
    }
}
```

### 再試行が失敗した場合にコードに到達する例外
<a name="retries-exception-types-during-retries"></a>

SDK の再試行メカニズムが問題を解決できない場合、例外はアプリケーションコードにスローされます。これらの例外タイプを理解することで、適切なエラー処理を実装できます。これらは再試行をトリガーする例外*ではなく*、 SDK によって内部的に処理されます。

再試行が枯渇または無効になると、コードは次のタイプの例外をキャッチします。

再試行後のサービス例外  
すべての再試行が失敗すると、コードは最後の再試行が失敗する原因となった最終的なサービス例外 ( のサブクラス`AwsServiceException`) をキャッチします。これは、スロットリングエラー、サーバーエラー、または SDK が再試行によって解決できなかったその他のサービス固有の例外である可能性があります。

再試行後のネットワーク例外  
再試行のたびにネットワークの問題が解決されない場合、コードは接続タイムアウト、DNS 解決の失敗、SDK が解決できなかったその他の接続の問題など、`ClientException`インスタンスを検出します。

アプリケーションでこれらの例外を処理するには、次のパターンを使用します。

```
try {
    s3Client.getObject { 
        bucket = "amzn-s3-demo-bucket"
        key = "my-key" 
    }
} catch (e: AwsServiceException) {
    // Service-side errors that persisted through all retries.
    println("Service error after retries: ${e.errorDetails?.errorCode} - ${e.message}")
    
    // Handle specific service errors that couldn't be resolved.
    if (e.errorDetails?.errorCode == "ServiceQuotaExceededException" || 
        e.errorDetails?.errorCode == "ThrottlingException") {
        println("Rate limiting persisted - consider longer delays or quota increase")
    }
} catch (e: ClientException) {
    // Client-side errors (persistent network issues, DNS resolution failures, etc.)
    println("Client error after retries: ${e.message}")
}
```

## 再試行動作のカスタマイズ
<a name="retries-customizing"></a>

以下のセクションでは、特定のユースケースに合わせて SDK の再試行動作をカスタマイズする方法を示します。

### 最大試行回数を設定する
<a name="retires-max-attempts"></a>

クライアントの構築中に [`retryStrategy`DSL ブロック](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries/-standard-retry-strategy/-config/-builder/index.html)のデフォルトの最大試行回数 (3) をカスタマイズできます。

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        maxAttempts = 5
    }
}
```

前のスニペットで示した DynamoDB サービスクライアントでは、SDK は最大 5 回失敗する API コールを試行します (最初の試行と 4 回の再試行）。

次のスニペットに示すように、最大試行回数を 1 に設定することで、自動再試行を完全に無効にできます。

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        maxAttempts = 1  // The SDK makes no retries.
    }
}
```

### 遅延とバックオフを設定する
<a name="retries-delays-backoff"></a>

再試行が必要な場合、デフォルトの再試行戦略は次の試行の前に待機します。最初の再試行の遅延は小さいですが、それ以降の再試行の遅延は指数関数的に増加します。最大遅延量は、大きくなりすぎないように上限が設定されます。

最後に、すべての試行間の遅延にランダムジッターが適用されます。ジッタは、再試行ストームを引き起こす可能性のある大規模なフリートの影響を緩和するのに役立ちます。(エクスポネンシャルバックオフとジッターの詳細については、この[AWS アーキテクチャブログの投稿](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/)を参照してください）。

遅延パラメータは [`delayProvider`DSL ブロック](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-exponential-backoff-with-jitter/-config/index.html)で設定できます。

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        delayProvider {
            initialDelay = 100.milliseconds
            maxBackoff = 5.seconds
        }
    }
}
```

前のスニペットに示されている設定では、クライアントは最初の再試行を最大 100 ミリ秒遅延します。再試行間の最大時間は 5 秒です。

遅延とバックオフの調整には、次のパラメータを使用できます。


| パラメータ | デフォルトの値 | 説明 | 
| --- | --- | --- | 
| initialDelay | 10 ミリ秒 | 最初の再試行の最大遅延時間。ジッターを適用すると、実際の遅延量が少なくなる可能性があります。 | 
| jitter | 1.0 (フルジッター) |  計算された遅延をランダムに減らす最大振幅。デフォルト値の 1.0 は、計算された遅延を最大 100% (0 など) まで減らすことができることを意味します。値 0.5 は、計算された遅延を最大半分に減らすことができることを意味します。したがって、最大遅延は 10 ミリ秒で、5 ミリ秒から 10 ミリ秒の範囲で短縮できます。値 0.0 は、ジッターが適用されないことを意味します。  ️ジッター設定は高度な機能です。この動作のカスタマイズは通常お勧めしません。   | 
| maxBackoff | 20 秒 | 試行に適用される最大遅延時間。この値を設定すると、その後の試行の間に発生する指数関数的な増加が制限され、計算された最大値が大きすぎることが防止されます。このパラメータは、ジッターが適用されるまでの計算遅延を制限します。適用されると、ジッターによって遅延がさらに減少する可能性があります。 | 
| scaleFactor | 1.5 | 後続の最大遅延が増加する指数ベース。たとえば、 `initialDelay`が 10 ミリ秒、 `scaleFactor`が 1.5 の場合、次の最大遅延が計算されます。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/sdk-for-kotlin/latest/developer-guide/retries.html)ジッターを適用すると、各遅延の実際の量が少なくなる可能性があります。 | 

### 再試行トークンバケットを設定する
<a name="retries-token-bucket"></a>

デフォルトのトークンバケット設定を調整することで、標準の再試行戦略の動作をさらに変更できます。再試行トークンバケットは、成功する可能性が低く、タイムアウトやスロットリングの失敗など、解決に時間がかかる可能性のある再試行を減らすのに役立ちます。

**重要**  
トークンバケット設定は高度な機能です。この動作のカスタマイズは通常お勧めしません。

再試行するたびに (オプションで最初の試行を含む）、トークンバケットから一部の容量が減少します。減少する量は、試行のタイプによって異なります。例えば、一時的なエラーを再試行すると安くなりますが、タイムアウトやスロットリングエラーを再試行するとコストが高くなる可能性があります。

試行が成功すると、バケットに容量が返されます。バケットは最大容量を超えて増分したり、ゼロ未満に減らしたりすることはできません。

`useCircuitBreakerMode` 設定の値に応じて、 は容量を 0 未満に減らそうとすると、次のいずれかの結果になります。
+ 設定が TRUE の場合、例外がスローされます。たとえば、再試行回数が多すぎて、それ以上の再試行が成功する可能性が低い場合などです。
+ 設定が FALSE の場合、遅延が発生します。たとえば、バケットが再び十分な容量になるまで遅延します。

**注記**  
サーキットブレーカーがアクティブになると (トークンバケットが容量ゼロに達すると）、SDK は「再試行容量超過」というメッセージ`ClientException`とともに をスローします。これは、 AWS サービスではなく SDK の再試行ロジックから発生するため`AwsServiceException`、 ではなくクライアント側の例外です。この例外は、 オペレーションを試行せずにすぐにスローされるため、サービス停止中の再試行ストームを防ぐことができます。

トークンバケットパラメータは [`tokenBucket`DSL ブロック](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-standard-retry-token-bucket/-config/index.html)で設定できます。

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        tokenBucket {
            maxCapacity = 100
            refillUnitsPerSecond = 2
        }
    }
}
```

再試行トークンバケットのチューニングには、次のパラメータを使用できます。


| パラメータ | デフォルトの値 | 説明 | 
| --- | --- | --- | 
| initialTryCost | 0 | 最初の試行でバケットから減らす量。デフォルト値の 0 は、容量が減少しないため、最初の試行が停止または遅延しないことを意味します。 | 
| initialTrySuccessIncrement | 1 | 最初の試行が成功したときの容量の増加量。 | 
| maxCapacity | 500 | トークンバケットの最大容量。使用可能なトークンの数はこの数を超えることはできません。 | 
| refillUnitsPerSecond | 0 | 1 秒ごとにバケットに再追加された容量。値 0 は、容量が自動的に再追加されないことを意味します。(たとえば、試行が成功すると容量が増加します）。値 0 は TRUE useCircuitBreakerModeである必要があります。 | 
| retryCost | 5 | 一時的な障害後に試行するためにバケットから減少する量。試行が成功すると、同じ量がバケットに再増分されます。 | 
| timeoutRetryCost | 10 | タイムアウトまたはスロットリングの失敗後に試行するためにバケットから減少する量。試行が成功すると、同じ量がバケットに再増分されます。 | 
| useCircuitBreakerMode | TRUE | 容量を減らそうとすると、バケットの容量がゼロを下回る場合の動作を決定します。TRUE の場合、トークンバケットは再試行容量が存在しないことを示す例外をスローします。FALSE の場合、トークンバケットは十分な容量が補充されるまで試行を遅らせます。 | 

サーキットブレーカーの例外など、再試行シナリオ中にスローされる例外タイプの詳細については、「」を参照してください[再試行が失敗した場合にコードに到達する例外](#retries-exception-types-during-retries)。

### アダプティブ再試行を設定する
<a name="retries-adaptive-retries"></a>

標準の再試行戦略の代わりに、アダプティブ再試行戦略は、スロットリングエラーを最小限に抑えるための理想的なリクエストレートを求める高度なアプローチです。

**重要**  
アダプティブ再試行は高度な再試行モードです。この再試行戦略を使用することは通常お勧めしません。

アダプティブ再試行には、標準的な再試行のすべての機能が含まれます。クライアント側のレートリミッターを追加し、スロットリングされたリクエストのレートを、スロットリングされていないリクエストと比較して測定します。また、トラフィックが安全な帯域幅内に収まるように制限し、理想的にはスロットリングエラーをゼロに抑えます。

レートは、サービス条件やトラフィックパターンの変化にリアルタイムで適応し、それに応じてトラフィックのレートが増減する場合があります。重要な点として、レートリミッターはトラフィックが集中するシナリオでは初期の試行を遅延させる可能性があります。

`retryStrategy` メソッドに追加のパラメータを指定して、アダプティブ再試行戦略を選択します。レートリミッターパラメータは [`rateLimiter`DSL ブロック](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-adaptive-rate-limiter/-config/index.html)で設定できます。

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy(AdaptiveRetryStrategy) {
        maxAttempts = 10
        rateLimiter {
            minFillRate = 1.0
            smoothing = 0.75
        }
    }
}
```

**注記**  
アダプティブ再試行戦略では、クライアントが単一のリソース (1 つの DynamoDB テーブルまたは 1 つの Amazon S3 バケットなど) に対して動作することを前提としています。  
1 つのクライアントを複数のリソースに使用すると、1 つのリソースに関連するスロットリングまたは停止により、クライアントが他のすべてのリソースにアクセスするときにレイテンシーが増加し、失敗します。アダプティブ再試行戦略を使用する場合は、リソースごとに 1 つのクライアントを使用することをお勧めします。