

# REL05-BP05 クライアントタイムアウトを設定する
<a name="rel_mitigate_interaction_failure_client_timeouts"></a>

接続とリクエストにタイムアウトを適切に設定し、体系的に検証します。また、デフォルト値には依存しないでください。これらはワークロードの詳細を認識していないためです。

 **期待される成果:** クライアントのタイムアウトには、完了までに異常に時間がかかるリクエストを待つことに関連するクライアント、サーバー、およびワークロードにかかるコストを考慮する必要があります。タイムアウトの正確な原因を知ることはできないため、クライアントはサービスの知識を活用して、考えられる原因と適切なタイムアウトを予測する必要があります。 

 クライアント接続は、設定された値に基づいてタイムアウトします。タイムアウトが発生すると、クライアントはバックオフして再試行するか、 [サーキットブレーカーを開くかを決定します](https://martinfowler.com/bliki/CircuitBreaker.html)。これらのパターンは、根本的なエラー状態を悪化させる可能性のあるリクエストの発行を回避します。 

 **一般的なアンチパターン:** 
+  システムタイムアウトまたはデフォルトタイムアウトを認識していない。 
+  通常のリクエスト完了タイミングを認識していない。 
+  リクエストが完了するまでに異常に時間がかかる原因や、これらの完了を待つことによってクライアント、サービス、またはワークロードのパフォーマンスが低下する原因を認識していない。 
+  ネットワークに障害が発生して、タイムアウトに達したときだけリクエストが失敗する確率や、より短いタイムアウトを採用しないことでクライアントとワークロードのパフォーマンスにコストがかかることを認識していない。 
+  接続とリクエストの両方のタイムアウトシナリオはテストされていません。 
+  タイムアウトの設定が高すぎると、待機時間が長くなり、リソースの使用率が高くなる可能性があります。 
+  タイムアウトの設定が低すぎると、人為的な障害が発生します。 
+  サーキットブレーカーや再試行などのリモート呼び出しのタイムアウトエラーを処理するパターンを見落としています。 
+  サービス呼び出しエラー率、遅延に関するサービスレベル目標、および遅延異常値のモニタリングは考慮していません。これらのメトリクスから、タイムアウトが積極的または許容範囲が広いかを判断できます。 

 **このベストプラクティスを活用するメリット:** リモート呼び出しのタイムアウトは、リモート呼び出しの応答が異常に遅い場合やタイムアウトエラーがサービスクライアントによって適切に処理される場合にリソースを節約できるように、タイムアウトを適切に処理するように設定され、システムがタイムアウトを適切に処理するように設計されています。 

 **このベストプラクティスを活用しない場合のリスクレベル:** 高 

## 実装のガイダンス
<a name="implementation-guidance"></a>

 サービス依存関係呼び出しに接続タイムアウトとリクエストタイムアウトの両方を設定します。またこの設定は、通常プロセス全体のすべての呼び出しにも行います。多くのフレームワークにはタイムアウト機能が組み込まれていますが、デフォルト値が無限であるか、サービス目標の許容範囲を超えているものもあるので注意してください。値が高すぎると、クライアントがタイムアウトの発生を待機している間もリソースが消費され続けるため、タイムアウトの有用性が低下します。値が小さすぎると、再試行されるリクエストが多くなりすぎるため、バックエンドのトラフィックが増加し、レイテンシーが高くなってしまいます。場合によっては、すべてのリクエストが再試行されることになるため、完全な機能停止につながる恐れもあります。 

 タイムアウト戦略を決定する際には、次の点を考慮してください。 
+  リクエストの内容、ターゲットサービスの障害、またはネットワークパーティションの障害により、リクエストの処理に通常よりも時間がかかる場合があります。 
+  異常に高価なコンテンツを含むリクエストは、サーバーとクライアントのリソースを不必要に消費する可能性があります。この場合、これらのリクエストをタイムアウトさせて再試行しないことで、リソースを節約できます。また、サービスは、スロットルやサーバー側のタイムアウトにより、異常にコストが大きいコンテンツから身を守る必要があります。 
+  サービスの障害により異常に時間がかかるリクエストは、タイムアウトして再試行できます。リクエストと再試行のサービスコストを考慮する必要がありますが、原因が局所的な障害である場合は、再試行してもコストはかからず、クライアントリソースの消費量を削減できます。障害の性質によっては、タイムアウトによってサーバーリソースが解放されることもあります。 
+  リクエストまたはレスポンスがネットワークから配信されなかったために完了までに時間がかかるリクエストは、タイムアウトして再試行できます。リクエストまたはレスポンスが配信されなかったため、タイムアウトの長さに関係なく失敗に終わったことになります。この場合、タイムアウトしてもサーバーリソースは解放されませんが、クライアントリソースが解放され、ワークロードのパフォーマンスが向上します。 

 再試行やサーキットブレーカーなどの確立された設計パターンを活用して、タイムアウトをスムーズに処理し、フェイルファストアプローチをサポートします。[AWS SDK](https://docs.aws.amazon.com/index.html#sdks) そして [AWS CLI](https://aws.amazon.com/cli/) 接続タイムアウトとリクエストタイムアウトの両方を設定でき、エクスポネンシャルバックオフとジッターによる再試行も可能です。[AWS Lambda](https://aws.amazon.com/lambda/) 関数はタイムアウトの設定をサポートしており、 [AWS Step Functions を使用すると](https://aws.amazon.com/step-functions/)、AWS サービスおよび SDK との事前構築された統合を利用するローコードサーキットブレーカーを構築できます。[AWS App Mesh](https://aws.amazon.com/app-mesh/) Envoy はタイムアウトとサーキットブレーカー機能を提供します。 

## 実装手順
<a name="implementation-steps"></a>
+  リモートサービス呼び出しのタイムアウトを設定し、組み込みの言語タイムアウト機能またはオープンソースのタイムアウトライブラリを活用してください。 
+  ワークロードが AWS SDK を使用して呼び出しを行う場合は、ドキュメントで言語固有のタイムアウト設定を確認してください。 
  + [ Python ](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html)
  + [ PHP ](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.DefaultsMode.Configuration.html)
  + [ .NET ](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html)
  + [ Ruby ](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/timeout-duration.html)
  + [ Java ](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/best-practices.html#bestpractice5)
  + [ Go ](https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/retries-timeouts/#timeouts)
  + [ Node.js ](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html)
  + [ C\$1\$1 ](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/client-config.html)
+  ワークロードで AWS SDK や AWS CLI コマンドを使用する場合、以下の AWS [設定デフォルト](https://docs.aws.amazon.com/sdkref/latest/guide/feature-smart-config-defaults.html) を設定し、デフォルトタイムアウト値を設定してください。 `(connectTimeoutInMillis` そして `tlsNegotiationTimeoutInMillis)`。 
+  コマンドラインオプション [cli-connect-timeout](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html) `および` cli-read-timeout `を適用して、` AWS サービスへの 1 回限りの AWS CLI コマンドを制御します。 
+  リモートサービス呼び出しのタイムアウトをモニタリングし、エラーが続く場合はアラームを設定して、エラーシナリオにプロアクティブに対処できるようにします。 
+  タグ付けを [CloudWatch Metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/working_with_metrics.html) cli-read-timeout [CloudWatch 異常の検出](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Anomaly_Detection.html) オンコールエラー率、レイテンシーに関するサービスレベル目標、レイテンシーの異常値から、過度にアグレッシブなタイムアウトや許容範囲のタイムアウトの管理に関するインサイトが得られます。 
+  タイムアウトを [Lambda 関数に設定します](https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html#configuration-timeout-console)。 
+  API Gateway クライアントは、タイムアウトを処理するときに独自の再試行を実装する必要があります。API Gateway は、 [ダウンストリーム統合に対して 50 ミリ秒から 29 秒の統合タイムアウトをサポートし、](https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#api-gateway-execution-service-limits-table) 統合リクエストのタイムアウト時に再試行しません。 
+  タイムアウト時のリモート呼び出しを回避するには、 [サーキットブレーカーを開くかを決定します](https://martinfowler.com/bliki/CircuitBreaker.html) パターンを実装します。呼び出しが失敗しないように回線を開き、呼び出しが正常に応答したら回線を閉じます。 
+  コンテナベースのワークロードの場合は、組み込みのタイムアウトとサーキットブレーカーを活用するための [App Mesh Envoy](https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html) 機能を確認してください。 
+  AWS Step Functions を使用して、リモートサービス呼び出し用のローコードサーキットブレーカーを構築します。特に、ワークロードを簡素化するために AWS ネイティブ SDK とサポートされている Step Functions 統合を呼び出す場合に使用します。 

## リソース
<a name="resources"></a>

 **関連するベストプラクティス:** 
+  [REL05-BP03 再試行呼び出しを制御および制限する](rel_mitigate_interaction_failure_limit_retries.md) 
+  [REL05-BP04 フェイルファストとキューの制限](rel_mitigate_interaction_failure_fail_fast.md) 
+  [REL06-BP07 システムを通じたリクエストのエンドツーエンドのトレースをモニタリングする](rel_monitor_aws_resources_end_to_end.md) 

 **関連するドキュメント:** 
+  [AWS SDK: 再試行とタイムアウト](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html) 
+  [The Amazon Builders' Library: タイムアウト、再試行、ジッターによるバックオフ](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 
+ [ Amazon API Gateway クォータと重要事項 ](https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html)
+ [AWS Command Line Interface: コマンドラインオプション ](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html)
+ [AWS SDK for Java 2.x: API タイムアウトの設定 ](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/best-practices.html#bestpractice5)
+ [ 設定オブジェクトと設定リファレンスを使用した AWS Botocore ](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#using-the-config-object)
+ [AWS SDK for .NET: 再試行とタイムアウト ](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html)
+ [AWS Lambda: Lambda 関数オプションの設定 ](https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html)

 **関連サンプル:** 
+ [AWS Step Functions および Amazon DynamoDB を使用したサーキットブレーカーパターンの使用 ](https://aws.amazon.com/blogs/compute/using-the-circuit-breaker-pattern-with-aws-step-functions-and-amazon-dynamodb/)
+ [ Martin Fowler: サーキットブレーカー ](https://martinfowler.com/bliki/CircuitBreaker.html?ref=wellarchitected)

 **関連ツール:** 
+ [AWS SDK ](https://docs.aws.amazon.com/index.html#sdks)
+ [AWS Lambda](https://aws.amazon.com/lambda/)
+ [ Amazon SQS ](https://aws.amazon.com/sqs/)
+ [AWS Step Functions を使用すると ](https://aws.amazon.com/step-functions/)
+ [AWS Command Line Interface](https://aws.amazon.com/cli/)