

# 障害を軽減するため、または障害に耐えるために分散システムでの相互作用を設計する
<a name="design-interactions-in-a-distributed-system-to-mitigate-or-withstand-failures"></a>

 分散システムは、サーバーやサービスなどのコンポーネントを相互接続するために通信ネットワークを利用しています。このネットワークでデータの損失やレイテンシーがあっても、ワークロードは確実に動作する必要があります。分散システムのコンポーネントは、他のコンポーネントやワークロードに悪影響を及ぼさない方法で動作する必要があります。これらのベストプラクティスに従うことで、ワークロードはストレスや障害に耐え、より迅速に復旧し、障害の影響を軽減できます。これにより、平均復旧時間 (MTTR) が向上します。

 これらのベストプラクティスは障害を防ぎ、平均故障間隔 (MTBF) を改善します。

**Topics**
+ [REL05-BP01 該当するハードな依存関係をソフトな依存関係に変換するため、グレースフルデグラデーションを実装する](rel_mitigate_interaction_failure_graceful_degradation.md)
+ [REL05-BP02 リクエストのスロットル](rel_mitigate_interaction_failure_throttle_requests.md)
+ [REL05-BP03 再試行呼び出しを制御および制限する](rel_mitigate_interaction_failure_limit_retries.md)
+ [REL05-BP04 フェイルファストとキューの制限](rel_mitigate_interaction_failure_fail_fast.md)
+ [REL05-BP05 クライアントタイムアウトを設定する](rel_mitigate_interaction_failure_client_timeouts.md)
+ [REL05-BP06 可能な限りシステムをステートレスにする](rel_mitigate_interaction_failure_stateless.md)
+ [REL05-BP07 緊急レバーを実装する](rel_mitigate_interaction_failure_emergency_levers.md)

# REL05-BP01 該当するハードな依存関係をソフトな依存関係に変換するため、グレースフルデグラデーションを実装する
<a name="rel_mitigate_interaction_failure_graceful_degradation"></a>

アプリケーションコンポーネントは、依存関係が使用できなくなっても、引き続きコア機能を実行する必要があります。少し古いデータ、代替データ、またはまったくデータを提供していない可能性があります。これにより、局所的な障害によるシステム全体の機能への影響を最小限に抑えながら、中心的なビジネス価値を提供できます。

 **期待される成果:** コンポーネントの依存関係が異常な場合でも、コンポーネント自体は機能しますが、パフォーマンスが低下します。コンポーネントの故障モードは通常の動作とみなしてください。ワークフローは、このような障害が完全な障害につながらないように、あるいは少なくとも予測可能で回復可能な状態になるように設計する必要があります。

 **一般的なアンチパターン:** 
+  必要な中核的なビジネス機能が特定されていない。依存関係に障害が発生してもコンポーネントが機能することをテストしていません。
+  エラーに関するデータを提供しない場合や、複数の依存関係のうち 1 つしか使用できず、結果の一部が返される場合もあります。
+  トランザクションが部分的に失敗すると、一貫性のない状態になる。
+  中央パラメータストアにアクセスする代替手段がない。
+  更新に失敗した結果、その結果を考慮せずにローカルステートを無効化または空にする。

 **このベストプラクティスを活用するメリット:** グレースフルデグラデーションを行うと、システム全体の可用性が向上し、障害が発生しても最も重要な機能の機能が維持されます。

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

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

 グレースフルデグラデーションを実装することで、依存関係の障害がコンポーネントの機能に与える影響を最小限に抑えることができます。コンポーネントが依存関係の障害を検出し、他のコンポーネントや顧客への影響を最小限に抑える方法で回避するのが理想的です。

 グレースフルデグラデーションを考慮した設計とは、依存関係の設計時に潜在的な障害モードを考慮することを意味します。障害モードごとに、コンポーネントのほとんどの機能、または少なくとも最も重要な機能を発信者または顧客に提供する方法を用意してください。これらの考慮事項は、テストや検証が必要な追加要件になる可能性があります。理想的には、1 つまたは複数の依存関係に障害が発生した場合でも、コンポーネントがコア機能を許容範囲内で実行できることが理想的です。

 これは技術的な議論であると同時にビジネス上の議論でもあります。すべてのビジネス要件は重要であり、可能であれば満たす必要があります。ただし、すべてが満たされない場合に何が起こるかをたずねることは依然として理にかなっています。システムは可用性と一貫性を保つように設計できますが、1 つの要件を削除しなければならない状況では、どちらの要件がより重要でしょうか。支払い処理については、一貫性があるかもしれません。リアルタイムアプリケーションの場合、可用性が高くなる可能性があります。カスタマー向けウェブサイトの場合、答えはカスタマーの期待するものによって異なる場合があります。

 これが何を意味するかは、コンポーネントの要件と、そのコア機能とみなすべき内容によって異なります。例えば、次のようになります。
+  e コマースウェブサイトでは、パーソナライズされたレコメンデーション、上位ランクの商品、顧客の注文状況など、複数の異なるシステムからのデータがランディングページに表示される場合があります。上流システムの 1 つに障害が発生した場合でも、エラーページを顧客に表示するのではなく、他のシステムすべてを表示する方が理にかなっています。
+  バッチ書き込みを実行するコンポーネントは、個々の操作のいずれかが失敗した場合でも、バッチの処理を続行できます。再試行メカニズムを実装するのは簡単なはずです。これは、どの操作が成功し、どの操作が失敗したか、なぜ失敗したかについての情報を呼び出し元に返すか、失敗したリクエストをデッドレターキューに入れて非同期再試行を実装することで実現できます。失敗した操作に関する情報も記録する必要があります。
+  トランザクションを処理するシステムは、個々の更新がすべて実行されたか、まったく実行されないかを確認する必要があります。分散トランザクションでは、同じトランザクションの後の操作が失敗した場合に備えて、Saga パターンを使用して以前の操作をロールバックできます。ここでの中心的な機能は一貫性を維持することです。
+  タイムクリティカルなシステムは、タイムリーに応答しない依存関係に対処しなければなりません。このような場合は、サーキットブレーカーパターンを使用できます。依存関係からの応答がタイムアウトし始めると、システムは追加の呼び出しが行われないクローズ状態に切り替えることができます。
+  アプリケーションはパラメータストアからパラメータを読み取ることができます。デフォルトのパラメータセットを使用してコンテナイメージを作成し、パラメータストアが利用できない場合にこれらを使用すると便利です。

 なお、コンポーネントに障害が発生した場合の経路は検査が必要で、主要経路よりも大幅に簡潔でなければなりません。一般的には、[フォールバック戦略は避けるべきです](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems/)。

## 実装手順
<a name="implementation-steps"></a>

 外部依存関係と内部依存関係を特定します。どのような種類の障害が発生する可能性があるかを検討してください。障害発生時に上流と下流のシステムやカスタマーへの悪影響を最小限に抑える方法を考えてください。

 依存関係の一覧と、失敗した場合に正常にデグレードする方法は次のとおりです。

1.  **依存関係の部分的な障害:** コンポーネントは、1 つのシステムへの複数の要求、または複数のシステムへの 1 つの要求のいずれかとして、下流システムに対して複数の要求を行うことができます。ビジネスの状況によっては、これに対するさまざまな処理方法が適切な場合があります (詳細については、実装ガイダンスの前述の例を参照してください)。

1.  **高負荷のためにダウンストリームシステムがリクエスト処理不可:** ダウンストリームシステムへのリクエストが一貫して失敗している場合、再試行を続けることは意味がありません。これにより、既に過負荷になっているシステムに追加の負荷がかかり、回復が困難になる可能性があります。ここでは、ダウンストリームシステムへのコールの失敗を監視するサーキットブレーカーパターンを利用できます。大量のコールが失敗すると、ダウンストリームシステムへのリクエストの送信が停止され、ダウンストリームシステムが再び使用可能かどうかをテストするコールがたまにしか送信されません。

1.  **パラメータストアが使用不可:** パラメータストアを変換するには、ソフト依存関係キャッシュを使用するか、コンテナイメージやマシンイメージに含まれる適切なデフォルトを使用できます。これらのデフォルトは最新の状態に保ち、テストスイートに含める必要があることに注意してください。

1.  **モニタリングサービスまたは非機能的依存関係が停止:** コンポーネントが断続的にログ、メトリクス、またはトレースを中央監視サービスに送信できない場合でも、通常どおりビジネス機能を実行するのが最善策です。メトリクスを長時間ログに記録したりプッシュしたりしないことは、ほとんどの場合受け入れられません。また、ユースケースによっては、コンプライアンス要件を満たすために完全な監査エントリが必要になる場合があります。

1.  **リレーショナルデータベースのプライマリインスタンスが停止している可能性がある:** Amazon Relational Database Service は、ほぼすべてのリレーショナルデータベースと同様に、プライマリライターインスタンスを 1 つだけ持つことができます。これにより、書き込みワークロードの単一障害点が生じ、スケーリングがより困難になります。これは、可用性を高めるためにマルチ AZ 構成を使用するか、スケーリングを向上させるために Amazon Aurora Serverless 構成を使用することで部分的に軽減できます。可用性要件が非常に高い場合は、プライマリライターにまったく依存しない方が理にかなっています。読み取り専用のクエリには、リードレプリカを使用できます。これにより、冗長性が確保され、スケールアップだけでなくスケールアウトも可能です。書き込みは、例えば、Amazon Simple Queue Service キューにバッファリングできるため、プライマリが一時的に使用できなくなっても、カスタマーからの書き込み要求を引き続き受け付けることができます。

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

 **関連ドキュメント:** 
+  [Amazon API Gateway: API リクエストを調整してスループットを向上させる](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [Circuit Breaker (「Release It\$1」書籍よりサーキットブレーカーをまとめたもの)](https://martinfowler.com/bliki/CircuitBreaker.html) 
+  [AWS でのエラーの再試行とエクスポネンシャルバックオフ](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [Michael Nygard 著「Release It\$1 Design and Deploy Production-Ready Software](https://pragprog.com/titles/mnee2/release-it-second-edition/)」 
+  [The Amazon Builders' Library: 分散システムでのフォールバックの回避](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [Amazon Builders' Library: 乗り越えられないキューバックログの回避](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs) 
+  [The Amazon Builders' Library: キャッシングの課題と戦略](https://aws.amazon.com/builders-library/caching-challenges-and-strategies/) 
+  [The Amazon Builders' Library: ジッターを伴うタイムアウト、再試行、およびバックオフ](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 

 **関連動画:** 
+  [Retry, backoff, and jitter: AWS re:Invent 2019: Introducing The Amazon Builders’ Library (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

# REL05-BP02 リクエストのスロットル
<a name="rel_mitigate_interaction_failure_throttle_requests"></a>

リクエストを制限して、予想外の需要の増加によるリソースの枯渇を緩和します。スロットリングレートを下回るリクエストは処理されますが、定義された制限を超えるリクエストは拒否され、リクエストがスロットリングされたことを示すメッセージが返されます。

 **期待される成果:** 突然のカスタマートラフィックの増加、フラッディング攻撃、または再試行ストームによる大量のスパイクは、リクエストスロットリングによって軽減され、サポートされているリクエスト量の通常の処理をワークロードが継続できるようになります。

 **一般的なアンチパターン:** 
+  API エンドポイントのスロットルは実装されていないか、予想される量を考慮せずにデフォルト値のままになっています。
+  API エンドポイントは負荷テストされておらず、スロットリング制限もテストされていません。
+  リクエストのサイズや複雑さを考慮せずにリクエストレートをスロットリングできます。
+  最大リクエストレートまたは最大リクエストサイズをテストしますが、両方を一緒にテストするわけではありません。
+  リソースは、テストで設定したのと同じ制限にプロビジョニングされません。
+  アプリケーション (A2A) API コンシューマーへの適用を目的とした使用プランは設定も検討もされていません。
+  水平方向にスケールするキューコンシューマーには、最大同時実行設定は設定されていません。
+  IP アドレスごとのレート制限は実装されていません。

 **このベストプラクティスを活用するメリット:** スロットル制限を設定したワークロードは、予期しない量のスパイクが発生しても、正常に動作し、受け入れられたリクエストの負荷を正常に処理できます。API やキューへのリクエストの急なスパイクや持続的なスパイクはスロットリングされ、リクエスト処理リソースを使い果たすことはありません。レート制限は、単一の IP アドレスまたは API コンシューマーからの大量のトラフィックがリソースを使い果たして他のコンシューマーに影響を与えないように、個々のリクエスタを制限します。

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

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

 サービスは、既知のキャパシティのリクエストを処理するように設計する必要があります。このキャパシティは、負荷テストによって確立できます。リクエストの到着率が制限を超えると、適切なレスポンスからリクエストがスロットリングされたことが通知されます。これにより、コンシューマーはエラーを処理して後で再試行できます。

 サービスにスロットリングの実装が必要な場合は、トークンがリクエストにカウントされるトークンバケットアルゴリズムの実装を検討してください。トークンは 1 秒あたりのスロットルレートで補充され、リクエストごとに 1 つのトークンで非同期に空になります。

![\[トークンバケットアルゴリズムを説明する図。\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/latest/reliability-pillar/images/token-bucket-algorithm.png)


 

 [Amazon API Gateway](https://aws.amazon.com/api-gateway/) は、アカウントとリージョンの制限に則ってトークンバケットアルゴリズムを実装します。使用プランに従ってクライアントごとに設定することが可能です。さらに、[Amazon Simple Queue Service (Amazon SQS)](https://aws.amazon.com/sqs/) と [Amazon Kinesis](https://aws.amazon.com/kinesis/) を使用することで、リクエストをバッファリングしてリクエストレートを均衡にし、対処可能なリクエストのスロットリングレートを高めることができます。最後に、[AWS WAF](https://aws.amazon.com/waf/) を使用してレート制限を実装することで、異常に高い負荷を発生させる特定の API コンシューマーをスロットリングします。

## 実装手順
<a name="implementation-steps"></a>

 API Gateway で API のスロットリング制限を設定し、制限を超過したときに「`429 Too Many Requests`」エラーを返すようにします。AWS AppSync および API Gateway エンドポイントで AWS WAF を使用すれば、IP アドレスごとにレート制限を有効にできます。さらに、システムが非同期処理に対応できる場合は、メッセージをキューまたはストリームに入れてサービスクライアントへの応答を高速化できます。これにより、より高いスロットルレートにバーストできます。

 非同期処理の場合、Amazon SQS を AWS Lambda のイベントソースとして設定しているときは、[最大同時実行数を設定](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#events-sqs-max-concurrency)することで、イベント率の上昇によって、ワークロードやアカウント内の他のサービスに必要な、使用可能なアカウントの同時実行クォータが消費されることを回避できます。

 API Gateway ではトークンバケットのマネージド実装が行われますが、API Gateway を使用できない場合は、お使いのサービス用のトークンバケットの、言語固有のオープンソース実装 (「参考文献」内の「関連する例」を参照) を利用できます。
+  [API Gateway のスロットリング制限](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html)は、リージョンごとのアカウントレベル、ステージごとの API、使用プランのレベルごとの API キーで理解し、設定します。
+  [AWS WAF レート制限ルール](https://aws.amazon.com/blogs/security/three-most-important-aws-waf-rate-based-rules/)を API Gateway および AWS AppSync エンドポイントに適用してフラッドから保護し、悪意のある IP をブロックします。A2A コンシューマー向けの AWS AppSync API キーにレート制限ルールを設定することもできます。
+  AWS AppSync API のレート制限よりも高度なスロットリング制御が必要かどうかを検討し、必要な場合は AWS AppSync エンドポイントの前に API Gateway を設定します。
+  Amazon SQS キューが Lambda キューコンシューマーのトリガーとして設定されているときは、[最大同時実行数](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#events-sqs-max-concurrency)は、サービスレベルの目標達成に十分に対応できる値、かつ他の Lambda 関数に影響を与える同時実行の制限を消費しない値に設定します。Lambda でキューを使用する場合は、同じアカウントおよびリージョン内の他の Lambda 関数に予約された同時実行を設定することを検討します。
+  API Gateway を、Amazon SQS または Kinesis とのネイティブサービス統合と共に使用して、リクエストをバッファリングします。
+  API Gateway を使用できない場合は、言語固有のライブラリを調べて、ワークロード用のトークンバケットアルゴリズムを実装してください。サンプルセクションを確認して、適切なライブラリを見つけるために独自の調査を行ってください。
+  設定する予定の、または引き上げを許可する予定の制限をテストし、テストした制限を文書化します。
+  テストで設定した上限を超えて制限を増やさないでください。制限を増やす場合は、増やす前に、プロビジョニングされたリソースが既にテストシナリオのものと同等かそれ以上であることを確認してください。

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

 **関連するベストプラクティス:** 
+  [REL04-BP03 継続動作を行う](rel_prevent_interaction_failure_constant_work.md) 
+  [REL05-BP03 再試行呼び出しを制御および制限する](rel_mitigate_interaction_failure_limit_retries.md) 

 **関連ドキュメント:** 
+  [Amazon API Gateway: スループットを高めるために API リクエストをスロットリングする](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+ [AWS WAF: レートベースのルールステートメント](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-rate-based.html)
+ [Introducing maximum concurrency of AWS Lambda when using Amazon SQS as an event source](https://aws.amazon.com/blogs/compute/introducing-maximum-concurrency-of-aws-lambda-functions-when-using-amazon-sqs-as-an-event-source/)
+ [AWS Lambda: 最大同実行数](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#events-sqs-max-concurrency)

 **関連する例:** 
+ [The three most important AWS WAF rate-based rules](https://aws.amazon.com/blogs/security/three-most-important-aws-waf-rate-based-rules/)
+ [Java Bucket4j](https://github.com/bucket4j/bucket4j)
+ [Python token-bucket](https://pypi.org/project/token-bucket/)
+ [Node token-bucket](https://www.npmjs.com/package/tokenbucket)
+ [.NET System Threading Rate Limiting](https://www.nuget.org/packages/System.Threading.RateLimiting)

 **関連動画:** 
+ [Implementing GraphQL API security best practices with AWS AppSync](https://www.youtube.com/watch?v=1ASMLeJ_15U)

 **関連ツール:** 
+ [Amazon API Gateway](https://aws.amazon.com/api-gateway/)
+ [AWS AppSync](https://aws.amazon.com/appsync/)
+ [Amazon Simple Queue Service](https://aws.amazon.com/sqs/)
+ [Amazon Kinesis](https://aws.amazon.com/kinesis/)
+ [AWS WAF](https://aws.amazon.com/waf/)
+ [Virtual Waiting Room on AWS](https://aws.amazon.com/solutions/implementations/virtual-waiting-room-on-aws/)

# REL05-BP03 再試行呼び出しを制御および制限する
<a name="rel_mitigate_interaction_failure_limit_retries"></a>

エクスポネンシャルバックオフを使用して、各再試行の間隔を徐々に長くしてリクエストを再試行します。再試行間隔をランダム化するために、再試行間にジッターを導入します。最大再試行回数を制限します。

 **期待される成果:** 分散ソフトウェアシステムの一般的なコンポーネントには、サーバー、ロードバランサー、データベース、DNS サーバーが含まれます。通常の操作では、これらのコンポーネントは一時的なエラーや限定的なエラーを含むリクエストに応答できます。また、再試行してもエラーが続くリクエストにも応答できます。クライアントがサービスにリクエストを行うと、そのリクエストはメモリ、スレッド、接続、ポート、またはその他の限られたリソースを含むリソースを消費します。再試行の制御と制限は、リソースを解放して消費を最小限に抑え、負荷がかかっているシステムコンポーネントに負荷がかからないようにするための戦略です。

 クライアントのリクエストがタイムアウトになったり、エラーレスポンスが返されたりした場合は、再試行するかどうかを決定する必要があります。再試行する場合は、ジッターと最大再試行値によるエクスポネンシャルバックオフを行います。その結果、バックエンドのサービスとプロセスの負荷が軽減され、自己修復にかかる時間が短縮されるため、復旧が速くなり、リクエストサービスが正常に処理されます。

 **一般的なアンチパターン:** 
+  エクスポネンシャルバックオフ、ジッター、最大再試行値を追加せずに再試行を実装します。バックオフとジッターは、同じ間隔で意図せずに調整された再試行による人為的なトラフィックのスパイクを防ぐのに役立ちます。
+  その効果をテストしたり、再試行シナリオをテストせずに再試行が既に SDK に組み込まれていたりすることを前提に再試行を実装します。
+  公開されている依存関係のエラーコードを理解できず、許可の欠如、設定エラー、または手動による介入なしでは解決できないと思われるその他の状態を示す明確な原因があるエラーを含め、すべてのエラーを再試行することになります。
+  根本的な問題を明らかにして対処できるように、繰り返し発生するサービス障害の監視や警告など、オブザーバビリティのプラクティスには触れていません。
+  組み込みまたはサードパーティーの再試行機能で十分な場合は、カスタムの再試行メカニズムを開発します。
+  アプリケーションスタックの複数のレイヤーで再試行すると、再試行が複雑になり、再試行の大混乱の中でさらにリソースを消費します。これらのエラーが依存しているアプリケーションの依存関係にどのように影響するかを必ず理解し、再試行は 1 つのレベルでのみ実装してください。
+  べき等性を持たないサービスコールを再試行すると、結果が重複するなどの予期しない影響が発生します。

 **このベストプラクティスを活用するメリット:** 再試行は、リクエストが失敗したときにクライアントが希望する結果を得るのに役立ちますが、必要な応答を得るまでにサーバーの時間を多く消費します。障害がまれな場合や一時的な場合は、再試行しても問題ありません。リソースの過負荷が原因で障害が発生した場合、再試行は事態を悪化させる可能性があります。クライアントの再試行にジッターを伴うエクスポネンシャルバックオフを追加することで、リソース過負荷が原因で障害が発生した場合でも、サーバーを回復できます。ジッターを使用すると、リクエストがスパイクに陥るのを防ぎ、バックオフによって通常のリクエスト負荷に再試行を追加することによる負荷のエスカレーションが軽減されます。最後に、メタステーブル障害の原因となるバックログが作成されないように、最大再試行回数または経過時間を設定することが重要です。

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

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

 再試行呼び出しを制御および制限します。エクスポネンシャルバックオフを使用して、徐々に長い間隔で再試行します。再試行間隔をランダム化するジッターを導入し、再試行の最大数を制限します。

 一部の AWS SDK は、デフォルトで再試行とエクスポネンシャルバックオフを実装しています。ワークロードに該当する場合は、これらの組み込み AWS 実装を使用してください。べき等性を持たせて再試行することでクライアントの可用性が向上するサービスを呼び出すときも、同様のロジックをワークロードに実装します。タイムアウトの時間と、再試行をいつ停止するのかをユースケースに基づいて決めます。こうした再試行のユースケースに対応するテストシナリオを構築し、実行してください。

## 実装手順
<a name="implementation-steps"></a>
+  アプリケーションスタック内の最適なレイヤーを決定して、アプリケーションが依存するサービスの再試行を実装してください。
+  選択した言語に対してエクスポネンシャルバックオフとジッターを伴う実証済みの再試行戦略を実装している既存の SDK に注意し、独自の再試行実装を作成するよりもこれらを優先してください。
+  再試行を行う前に、[サービスがべき等性を持っている](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/)ことを確認します。再試行を実装したら、必ずテストを行い、本番環境で定期的に実行するようにしてください。
+  AWS サービス API を呼び出すときは、[AWS SDK](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html) と [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-retries.html) を使用し、再試行の設定オプションを把握します。デフォルトがユースケースに適しているかどうかを判断し、テストし、必要に応じて調整します。

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

 **関連するベストプラクティス:** 
+  [REL04-BP04 変更操作をべき等にする](rel_prevent_interaction_failure_idempotent.md) 
+  [REL05-BP02 リクエストのスロットル](rel_mitigate_interaction_failure_throttle_requests.md) 
+  [REL05-BP04 フェイルファストとキューの制限](rel_mitigate_interaction_failure_fail_fast.md) 
+  [REL05-BP05 クライアントタイムアウトを設定する](rel_mitigate_interaction_failure_client_timeouts.md) 
+  [REL11-BP01 ワークロードのすべてのコンポーネントをモニタリングして障害を検知する](rel_withstand_component_failures_monitoring_health.md) 

 **関連ドキュメント:** 
+  [AWS でのエラーの再試行とエクスポネンシャルバックオフ](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [Amazon Builders' Library: ジッターを伴うタイムアウト、再試行、およびバックオフ](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 
+ [Exponential Backoff and Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/)
+ [Making retries safe with idempotent APIs](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/)

 **関連する例:** 
+ [Spring Retry](https://github.com/spring-projects/spring-retry)
+ [Resilience4j Retry](https://resilience4j.readme.io/docs/retry)

 **関連動画:** 
+  [Retry, backoff, and jitter: AWS re:Invent 2019: Introducing The Amazon Builders’ Library (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

 **関連ツール:** 
+ [AWS SDKs and Tools: Retry behavior](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html)
+ [AWS Command Line Interface: AWS CLI 再試行](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-retries.html)

# REL05-BP04 フェイルファストとキューの制限
<a name="rel_mitigate_interaction_failure_fail_fast"></a>

サービスがリクエストに正常に応答できない場合は、すぐに失敗します。これにより、リクエストに関連付けられたリソースが解放され、リソースが不足した場合にサービスを復旧できます。フェイルファストは確立されたソフトウェア設計パターンであり、これを活用して信頼性の高いワークロードをクラウド上に構築できます。キューイングは、負荷をスムーズにし、非同期処理が許容できる場合にクライアントがリソースを解放できるようにする、確立されたエンタープライズ統合パターンでもあります。サービスが通常の状態では正常に応答できるが、リクエストのレートが高すぎると失敗する場合は、キューを使用してリクエストをバッファします。ただし、長いキューのバックログの蓄積は許可しないでください。クライアントが既に処理を停止している古いリクエストを処理する原因となる可能性があるためです。

 **期待される成果:** システムにリソースの競合、タイムアウト、例外、またはグレー障害が発生してサービスレベル目標を達成できない場合、フェイルファスト戦略を使用するとシステムをより迅速に回復できます。トラフィックの急増を吸収する必要があり、非同期処理に対応できるシステムでは、バックエンドサービスへのリクエストをバッファリングするキューを使用して、クライアントがリクエストを迅速にリリースできるようにすることで信頼性を向上できます。リクエストをキューにバッファリングする際には、克服できないバックログを回避するためにキュー管理戦略が実装されます。

 **一般的なアンチパターン:** 
+  メッセージキューを実装するが、システムに障害が発生したことを検出するデッドレターキュー (DLQ) やアラームを DLQ ボリュームに設定しない。
+  キュー内のメッセージの経過時間を測定するのではなく、キューのコンシューマーが遅れたり、エラーが発生して再試行が発生したりするタイミングを把握するためのレイテンシーの測定です。
+  業務上の必要がなくなった場合に、これらのメッセージを処理する価値がない場合に、未処理のメッセージをキューから消去しない。
+  先入れ先出し (FIFO) キューを後入れ先出し (LIFO) キューに設定すると、クライアントのニーズにより適切に対応できます。例えば、厳密な順序付けが不要で、バックログ処理により新規リクエストや時間的制約のあるリクエストがすべて遅延し、その結果、すべてのクライアントでサービスレベル違反が発生するような場合です。
+  仕事の受け入れを管理してリクエストを内部キューに入れる API を公開する代わりに、内部キューをクライアントに公開します。
+  1 つのキューに多数の作業リクエストタイプをまとめると、リソース需要がリクエストタイプ全体に分散され、バックログの状態が悪化する可能性があります。
+  異なるモニタリング、タイムアウト、リソース割り当てが必要な場合でも、複雑なリクエストと単純なリクエストを同じキューで処理します。
+  エラーを適切に処理できる上位レベルのコンポーネントに例外をバブリングするフェイルファストメカニズムをソフトウェアで実装するために、入力を検証したり、アサーションを使用したりしない。
+  リクエストルーティングから障害のあるリソースを削除しない。特に、クラッシュや再起動、断続的な依存関係の障害、容量の低下、ネットワークのパケットロスなどにより、障害がグレーで成功と失敗の両方を示している場合。

 **このベストプラクティスを活用するメリット:** フェイルファストなシステムはデバッグや修正が容易で、多くの場合、リリースが本稼働環境にパブリッシュされる前に、コーディングや構成上の問題を明らかにすることができます。効果的なキューイング戦略を組み込んだシステムは、トラフィックの急増や断続的なシステム障害状態に対する回復力と信頼性が向上します。

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

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

 フェイルファスト戦略は、ソフトウェアソリューションにコード化することも、インフラストラクチャに構成することもできます。キューは、高速に障害が発生するだけでなく、システムコンポーネントを切り離してスムーズに負荷をかけるための単純でありながら強力なアーキテクチャ手法です。[Amazon CloudWatch](https://aws.amazon.com/cloudwatch/) には、障害をモニタリングし、警告する機能があります。システムに障害が発生していることが判明したら、障害が発生したリソースからフェイルアウェイするなどの緩和策を講じることができます。システムが [Amazon SQS](https://aws.amazon.com/sqs/) やその他キューテクノロジーを使用してキューを実装し、負荷を軽減している場合、そのシステムは、キューのバックログやメッセージ使用の失敗の、管理方法を検討しておく必要があります。

## 実装手順
<a name="implementation-steps"></a>
+  プログラムによるアサーションまたは特定のメトリクスをソフトウェアに実装し、それらを使用してシステムの問題を明示的に警告します。Amazon CloudWatch を使用すると、アプリケーションのログパターンや SDK の計測に基づいてメトリクスとアラームを作成することができます。
+  CloudWatch メトリクスとアラームを使用して、リソースに障害が発生して処理に遅延が発生したり、リクエストの処理が繰り返し失敗したりしないようにします。
+  Amazon SQS を使用してリクエストを受け入れ、リクエストを内部キューに追加し、メッセージ生成クライアントに成功メッセージで応答する API を設計することで非同期処理を使用します。これにより、バックエンドキューのコンシューマーがリクエストを処理している間、クライアントはリソースを解放して他の作業に進むことができます。
+  現在とメッセージのタイムスタンプを比較することで、メッセージをキューから取り出すたびに CloudWatch メトリクスを生成し、キューの処理遅延を測定およびモニタリングします。
+  障害によってメッセージ処理が正常に行われなかった、またはサービスレベル契約の範囲内で処理できない量のトラフィックが急増した場合は、古いトラフィックや過剰なトラフィックをスピルオーバーキューに振り分けます。これにより、キャパシティに空きがあれば、新しい作業や古い作業を優先的に処理できます。この手法は LIFO 処理の近似値であり、すべての新規作業で通常のシステム処理が可能になります。
+  処理できないメッセージをバックログから後で調査して解決できる場所に移動するには、デッドレターキューまたはリドライブキューを使用します。
+  再試行するか、許容範囲内であれば、メッセージのタイムスタンプと現在を比較して、要求元のクライアントに関係のないメッセージは破棄して、古いメッセージを削除してください。

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

 **関連するベストプラクティス:** 
+  [REL04-BP02 疎結合の依存関係を実装する](rel_prevent_interaction_failure_loosely_coupled_system.md) 
+  [REL05-BP02 リクエストのスロットル](rel_mitigate_interaction_failure_throttle_requests.md) 
+  [REL05-BP03 再試行呼び出しを制御および制限する](rel_mitigate_interaction_failure_limit_retries.md) 
+  [REL06-BP02 メトリクスを定義および計算する (集計)](rel_monitor_aws_resources_notification_aggregation.md) 
+  [REL06-BP07 システムを通じたリクエストのエンドツーエンドのトレースをモニタリングする](rel_monitor_aws_resources_end_to_end.md) 

 **関連ドキュメント:** 
+ [乗り越えられないキューバックログの回避](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs/)
+  [Fail Fast](https://www.martinfowler.com/ieeeSoftware/failFast.pdf) 
+ [Amazon SQS キュー内のメッセージのバックログの増加を防ぐにはどうすればよいですか?](https://repost.aws/knowledge-center/sqs-message-backlog)
+ [Elastic Load Balancing: Zonal Shift](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/zonal-shift.html)
+ [Amazon Application Recovery Controller: トラフィックフェイルオーバーのルーティングコントロール](https://docs.aws.amazon.com/r53recovery/latest/dg/getting-started-routing-controls.html)

 **関連する例:** 
+ [Enterprise Integration Patterns: Dead Letter Channel](https://www.enterpriseintegrationpatterns.com/patterns/messaging/DeadLetterChannel.html)

 **関連動画:** 
+  [AWS re:Invent 2022 - Operating highly available Multi-AZ applications](https://www.youtube.com/watch?v=mwUV5skJJ0s) 

 **関連ツール:** 
+ [Amazon Simple Queue Service](https://aws.amazon.com/sqs/)
+ [Amazon MQ](https://aws.amazon.com/amazon-mq/)
+ [AWS IoT Core](https://aws.amazon.com/iot-core/)
+ [Amazon CloudWatch](https://aws.amazon.com/cloudwatch/)

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

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

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

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

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

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

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

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

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

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

 再試行やサーキットブレーカーなどの確立された設計パターンを活用して、タイムアウトをスムーズに処理し、フェイルファストアプローチをサポートします。[AWSSDK](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 コマンドを使用するときは、`connectTimeoutInMillis` と `tlsNegotiationTimeoutInMillis` の AWS [設定デフォルト](https://docs.aws.amazon.com/sdkref/latest/guide/feature-smart-config-defaults.html) を設定し、デフォルトのタイムアウト値を設定します。
+  [コマンドラインオプション](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html) の `cli-connect-timeout` と `cli-read-timeout` を適用して、AWS のサービスの 1 回限りの AWS CLI コマンドを制御します。
+  リモートサービス呼び出しのタイムアウトをモニタリングし、エラーが続く場合はアラームを設定して、エラーシナリオにプロアクティブに対処できるようにします。
+  コールエラー率、レイテンシーに関するサービスレベル目標、レイテンシーの外れ値に関する [CloudWatch メトリクス](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/working_with_metrics.html)と [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) 
+  [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)
+ [AWSBotocore using the config object and Config Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#using-the-config-object)
+ [AWS SDK for .NET: Retries and Timeouts](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html)
+ [AWS Lambda: AWS Lambda 関数の設定](https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html)

 **関連する例:** 
+ [Using the circuit breaker pattern with AWS Step Functions and Amazon DynamoDB](https://aws.amazon.com/blogs/compute/using-the-circuit-breaker-pattern-with-aws-step-functions-and-amazon-dynamodb/)
+ [Martin Fowler: CircuitBreaker](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 Simple Queue Service](https://aws.amazon.com/sqs/)
+ [AWS Step Functions](https://aws.amazon.com/step-functions/)
+ [AWS Command Line Interface](https://aws.amazon.com/cli/)

# REL05-BP06 可能な限りシステムをステートレスにする
<a name="rel_mitigate_interaction_failure_stateless"></a>

 状態を必要としないシステム、または状態をオフロードするシステム (異なるクライアントリクエスト間にディスクやメモリ内のローカルに保存されたデータへの依存がない) にしてください。これにより、可用性に影響を与えることなく、サーバーをいつでも置き換えることができます。

 ユーザーまたはサービスがアプリケーションと対話するとき、セッションを形成する一連のやりとりを頻繁に実行します。セッションは、ユーザーがアプリケーションを使用している間、リクエスト間で持続するユーザー固有のデータです。ステートレスアプリケーションは、以前のやりとりの知識を必要とせず、セッション情報を保存しません。

 ステートレスな設計にすれば、あとは AWS Lambda や AWS Fargate などのサーバーレスコンピューティングサービスを利用できます。

 サーバーの置き換えに加えて、ステートレスアプリケーションのもう 1 つの利点は、利用可能なコンピューティングリソース (EC2 インスタンスや AWS Lambda 関数など) がどのようなリクエストにも対応できるため、水平方向にスケールできることです。

 **このベストプラクティスを活用するメリット:** ステートレスに設計されたシステムは水平スケーリングへの適応性が高いため、トラフィックや需要の変化に応じてキャパシティを増やしたり減らしたりすることが可能です。また、本質的に耐障害性に優れており、アプリケーション開発に柔軟性と俊敏性をもたらします。

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

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

 アプリケーションをステートレスにします。ステートレスアプリケーションは、水平スケーリングが可能であり、個別ノードの障害に耐性があります。アーキテクチャ内の状態を維持するアプリケーションのコンポーネントを分析して理解します。これにより、ステートレス設計への移行で考えられる影響を評価できます。ステートレスアーキテクチャはユーザーデータを切り離し、セッションデータをオフロードします。各コンポーネントを個別にスケールし、変化するワークロードの需要に対応することでリソースの使用率を最適化できる柔軟性が得られます。

### 実装手順
<a name="implementation-steps"></a>
+  アプリケーション内のステートフルなコンポーネントを特定して理解します。
+  ユーザーデータをコアアプリケーションロジックから分離して管理することで、データを切り離します。
  +  [Amazon Cognito](https://aws.amazon.com/cognito/) では、[アイデンティティプール](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-identity-pools.html)、[ユーザープール](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-cognito-user-pools.html)、[Amazon Cognito Sync](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-sync.html) などの機能を使用することでユーザーデータをアプリケーションコードから切り離すことができます。
  +  [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) を使用すると、シークレットを一元化された安全な場所に保管することでユーザーデータを切り離すことができます。つまり、アプリケーションコードにシークレットを保存する必要がないため、安全性が高まります。
  +  イメージやドキュメントなどの構造化されていない大規模なデータを保存するときは [Amazon S3](https://aws.amazon.com/s3/) の使用を検討します。アプリケーションは必要に応じてこのデータを取得できるため、メモリに保存する必要はありません。
  +  ユーザープロファイルなどの情報を保存するときは [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) を使用します。アプリケーションでは、ほぼリアルタイムでこのデータをクエリできます。
+  セッションデータをデータベース、キャッシュ、または外部ファイルにオフロードします。
  +  セッションデータのオフロードに使用できる AWS のサービスには、[Amazon ElastiCache](https://aws.amazon.com/elasticache/)、Amazon DynamoDB、[Amazon Elastic File System](https://aws.amazon.com/efs/) (Amazon EFS)、[Amazon MemoryDB](https://aws.amazon.com/memorydb/) などがあります。
+  選択したストレージソリューションでは、どの状態とユーザーデータを持続しておく必要があるのかを特定した後、ステートレスアーキテクチャを設計します。

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

 **関連するベストプラクティス:** 
+  [REL11-BP03 すべてのレイヤーの修復を自動化する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_withstand_component_failures_auto_healing_system.html) 

 **関連ドキュメント:** 
+  [Amazon Builders' Library: 分散システムでのフォールバックの回避](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [Amazon Builders' Library: 乗り越えられないキューバックログの回避](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs) 
+  [Amazon Builders' Library: キャッシングの課題と戦略](https://aws.amazon.com/builders-library/caching-challenges-and-strategies/) 
+  [AWS のステートレスなウェブ層](https://docs.aws.amazon.com/whitepapers/latest/best-practices-wordpress/stateless-web-tier.html) 

# REL05-BP07 緊急レバーを実装する
<a name="rel_mitigate_interaction_failure_emergency_levers"></a>

 緊急レバーは、ワークロードの可用性に対する影響を軽減できる迅速なプロセスです。

 緊急レバーは、既知のテスト済みのメカニズムを使用して、コンポーネントや依存関係の動作を無効にしたり、スロットリングしたり、変更したりするためのものです。その効果として、想定外の需要増によるリソースの枯渇が原因となるワークロードの障害を軽減し、ワークロード内の重要ではないコンポーネントの障害の波及を抑制できます。

 **期待される成果:** 緊急レバーを実装することで、ワークロードに欠かせないコンポーネントの可用性を維持するための、問題がないことが確認されているプロセスを確立できます。緊急レバーが作動している間、ワークロードは意図的に性能を落とし (グレースフルデグラデーション)、ビジネスに不可欠な機能を引き続き実行します。グレースフルデグラデーションの詳細は、「[REL05-BP01 該当するハードな依存関係をソフトな依存関係に変換するため、グレースフルデグラデーションを実装する](https://docs.aws.amazon.com/wellarchitected/latest/framework/rel_mitigate_interaction_failure_graceful_degradation.html)」を参照してください。

 **一般的なアンチパターン:** 
+  重要ではない依存関係に障害が発生した場合に、主要ワークロードの可用性に影響が波及する。
+  重要ではないコンポーネントに障害が起きている間に、重要なコンポーネントの動作をテストまたは検証しない。
+  緊急レバーの作動または作動解除に関する決定的な基準が明確に定義されていない。

 **このベストプラクティスを活用するメリット:** 緊急レバーを実装すれば、予期せぬ需要の急増や、重要度の低い依存関係における障害などに対処するためのプロセスを確立してリゾルバーに提供することで、ワークロードに不可欠なコンポーネントの可用性を高めることができます。

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  ワークロードの重要なコンポーネントを特定します。
+  重要ではないコンポーネントに障害が起きても耐えられるように、ワークロードの重要なコンポーネントを設計し、構築します。
+  重要ではないコンポーネントで障害が発生している最中に、重要なコンポーネントの動作を検証するためのテストを実施します。
+  緊急レバーの手続き開始の基準となる適切な指標やトリガーを定義し、監視します。
+  緊急レバーを構成する手順 (手動または自動) を定義します。

### 実装手順
<a name="implementation-steps"></a>
+  ワークロード内のビジネスクリティカルなコンポーネントを特定します。
  +  ワークロードの技術的なコンポーネントをそれぞれ適切なビジネス機能にマッピングし、重要または非重要にランク分けします。Amazon の重要な機能および非重要な機能の例については、[「Any Day Can Be Prime Day: How Amazon.com Search Uses Chaos Engineering to Handle Over 84K Requests Per Second](https://community.aws/posts/how-search-uses-chaos-engineering)」を参照してください。
  +  これは技術上の決定でもビジネス上の決定でもあり、組織やワークロードによって異なります。
+  重要ではないコンポーネントに障害が起きても耐えられるように、ワークロードの重要なコンポーネントを設計し、構築します。
  +  依存関係の分析では、想定される障害モードをすべて検討し、緊急レバーのメカニズムを通じて、ダウンストリームのコンポーネントも重要な機能を利用できるか検証します。
+  緊急レバーが作動している間に、重要なコンポーネントの動作を検証するためのテストを実施してください。
  +  バイモーダル動作は防止してください。詳細については、「[REL11-BP05 静的安定性を使用してバイモーダル動作を防止する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_withstand_component_failures_static_stability.html)」を参照してください。
+  緊急レバーの手続き開始の基準となる指標を定義して監視し、警戒します。
  +  ワークロードに応じて、監視対象として適切な指標を判断してください。指標の例としては、レイテンシーや、依存関係へのリクエストの失敗回数などが該当します。
+  緊急レバーを構成する手順 (手動または自動) を定義します。
  +  これには、[負荷制限](https://aws.amazon.com/builders-library/using-load-shedding-to-avoid-overload/)、[リクエストのスロットリング](https://docs.aws.amazon.com/wellarchitected/latest/framework/rel_mitigate_interaction_failure_throttle_requests.html)、[グレースフルデグラデーション](https://docs.aws.amazon.com/wellarchitected/latest/framework/rel_mitigate_interaction_failure_graceful_degradation.html)の実装などのメカニズムが含まれます。

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

 **関連するベストプラクティス:** 
+  [REL05-BP01 該当するハードな依存関係をソフトな依存関係に変換するため、グレースフルデグラデーションを実装する](https://docs.aws.amazon.com/wellarchitected/latest/framework/rel_mitigate_interaction_failure_graceful_degradation.html) 
+  [REL05-BP02 リクエストのスロットル](https://docs.aws.amazon.com/wellarchitected/latest/framework/rel_mitigate_interaction_failure_throttle_requests.html) 
+  [REL11-BP05 静的安定性を使用してバイモーダル動作を防止する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_withstand_component_failures_static_stability.html) 

 **関連ドキュメント:** 
+ [安全なハンズオフデプロイメントの自動化](https://aws.amazon.com/builders-library/automating-safe-hands-off-deployments/)
+  [プライムデーがいつ来ても大丈夫: Amazon.com の検索機能がカオスエンジニアリングで 1 秒に 84,000 件以上のリクエストを処理する方法](https://community.aws/posts/how-search-uses-chaos-engineering) 

 **関連動画:** 
+ [AWS re:Invent 2020: Reliability, consistency, and confidence through immutability](https://www.youtube.com/watch?v=jUSYnRztttY)