

# ワークロードアーキテクチャ
<a name="a-workload-architecture"></a>

**Topics**
+ [REL 3 ワークロードサービスアーキテクチャをどのように設計すればよいですか?](w2aac19b9b7b5.md)
+ [REL 4 障害を防ぐために、分散システムでの操作をどのように設計すればよいですか?](w2aac19b9b7b7.md)
+ [REL 5 障害を緩和または耐えるために、分散システムの操作をどのように設計しますか?](w2aac19b9b7b9.md)

# REL 3 ワークロードサービスアーキテクチャをどのように設計すればよいですか?
<a name="w2aac19b9b7b5"></a>

サービス指向アーキテクチャ (SOA) またはマイクロサービスアーキテクチャを使用して、拡張性と信頼性の高いワークロードを構築します。サービス指向アーキテクチャ (SOA) は、サービスインターフェイスを介してソフトウェアコンポーネントを再利用できるようにする方法です。マイクロサービスアーキテクチャは、その一歩先を行き、コンポーネントをさらに小さくシンプルにしています。

**Topics**
+ [REL03-BP01 ワークロードをセグメント化する方法を選択する](rel_service_architecture_monolith_soa_microservice.md)
+ [REL03-BP02 特定のビジネスドメインと機能に重点を置いたサービスを構築する](rel_service_architecture_business_domains.md)
+ [REL03-BP03 API ごとにサービス契約を提供する](rel_service_architecture_api_contracts.md)

# REL03-BP01 ワークロードをセグメント化する方法を選択する
<a name="rel_service_architecture_monolith_soa_microservice"></a>

 アプリケーションの回復力要件を決定する際に、ワークロードのセグメント化は重要です。モノリシックアーキテクチャはできるだけ避ける必要があります。代わりに、どのアプリケーションコンポーネントをマイクロサービスに分けられるかを注意深く考慮します。アプリケーションの要件によっては、最終的にサービス指向アーキテクチャ (SOA) とマイクロサービスの組み合わせになることもあります。ステートレス化が可能なワークロードは、マイクロサービスとしてデプロイすることができます。 

 **期待される成果:** ワークロードは、サポート可能で、スケーラブルであり、可能な限り疎結合であるべきです。 

 ワークロードのセグメント化について選択を行う場合は、複雑さに対してどれだけメリットがあるかを考えてください。新製品のローンチ時に適しているものは、初期からスケーリングのことを考えて構築したワークロードとは異なります。既存のモノリスをリファクタリングする場合、アプリケーションがステートレスへの分解をどの程度サポートできるかを検討する必要があります。サービスを小さく分割することで、小規模で明確なチームが開発、管理することができます。しかし、サービスの規模が小さくなると、レイテンシーの増加、デバッグの複雑化、運用負荷の増大など、複雑な問題が発生する可能性があります。 

 **一般的なアンチパターン:** 
+  「 [マイクロサービス *Death Star*](https://mrtortoise.github.io/architecture/lean/design/patterns/ddd/2018/03/18/deathstar-architecture.html) 」とは、アトミックコンポーネントが強く依存しあっているために、1 つの失敗がより大きな失敗となり、コンポーネントがモノリスのように柔軟性が低く、壊れやすくなっている状態のことです。

 **このプラクティスを活用するメリット:** 
+  より特化したセグメントは、高い俊敏性、組織の柔軟性、およびスケーラビリティにつながる。 
+  サービス中断の影響が小さくなる。 
+  アプリケーションコンポーネントには異なる可用性要件があり、より特化したセグメント化によってサポートされることがある。 
+  ワークロードをサポートするチームの責任が明確に定義される。 

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

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

 ワークロードをセグメント化する方法に基づいてアーキテクチャタイプを選択します。SOA またはマイクロサービスアーキテクチャ (場合によってはモノリシックアーキテクチャ) を選択します。モノリスアーキテクチャから開始する場合でも、それがモジュラー型で、ユーザーの導入に合わせて製品がスケールされるにつれて最終的に SOA またはマイクロサービスに進化できることを確認する必要があります。SOA とマイクロサービスは、それぞれより小さなセグメントを提供し、最新のスケーラブルで信頼性の高いアーキテクチャとして好まれていますが、特にマイクロサービスアーキテクチャを展開する際には、トレードオフを考慮しなければなりません。 

 主なトレードオフとしては、分散コンピューティングアーキテクチャを採用することになり、ユーザーのレイテンシー要件を達成するのが難しくなることと、ユーザーインタラクションのデバッグとトレースにさらなる複雑さが生じることが挙げられます。AWS X-Ray を使ってこの問題の解決に役立てることができます。また、管理するアプリケーションの数が増え、複数の独立したコンポーネントを配置する必要があるため、運用が複雑になることも考慮しなければなりません。 

![\[モノリシック、サービス指向、マイクロサービスアーキテクチャの比較を表す図\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/2022-03-31/framework/images/monolith-soa-microservices-comparison.png)


## 実装手順
<a name="implementation-steps"></a>
+  アプリケーションのリファクタリングやビルドに適したアーキテクチャを決定します。SOA とマイクロサービスは、それぞれより小さなセグメンテーションを提供し、最新のスケーラブルで信頼性の高いアーキテクチャとして好まれます。SOA は、マイクロサービスの複雑さを回避しながら、より小さなセグメント化を達成するための優れた折衷案となり得ます。詳細については、 [マイクロサービスのトレードオフ](https://martinfowler.com/articles/microservice-trade-offs.html). 
+  ワークロードが適していて、組織がサポートできる場合は、最高の俊敏性と信頼性を実現するために、マイクロサービスアーキテクチャを使用すべきです。詳細については、 [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  モノリスを [*Strangler Fig* パターン](https://martinfowler.com/bliki/StranglerFigApplication.html) に従って、より小さいコンポーネントにリファクタリングします。これには、特定のアプリケーションコンポーネントを新しいアプリケーションとサービスに徐々に置き換えることが含まれます。[AWS Migration Hub Refactor Spaces](https://docs.aws.amazon.com/migrationhub-refactor-spaces/latest/userguide/what-is-mhub-refactor-spaces.html) は、増分リファクタリングの開始点として機能します。詳細については、「 [オンプレミスのレガシーワークロードをシームレスに移行する](https://aws.amazon.com/blogs/architecture/seamlessly-migrate-on-premises-legacy-workloads-using-a-strangler-pattern/)」を参照してください。
+  マイクロサービスを実装する場合、これらの分散したサービスが互いに通信できるようにするためのサービス検出メカニズムが必要になる場合があります。[AWS App Mesh](https://docs.aws.amazon.com/app-mesh/latest/userguide/what-is-app-mesh.html) をサービス指向アーキテクチャとともに使用することで、高い信頼性をもってサービスを検出し、サービスにアクセスできます。 [AWS Cloud Map](https://aws.amazon.com/cloud-map/) は、動的 DNS ベースのサービス検出にも使用できます。
+  モノリスから SOA へ移行する場合、[Amazon MQ](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/welcome.html) は、レガシーアプリケーションをクラウドで再設計する際に、サービスバスとしてギャップを埋めるのに役立ちます。
+  単一の共有されたデータベースがある既存のモノリスには、データを再編成して小さなセグメントにする方法を選択します。これは、ビジネスユニット、アクセスパターン、またはデータ構造によって行うことができます。リファクタリングプロセスのこの時点では、リレーショナルまたは非リレーショナル (NoSQL) タイプのデータベースを選択して進めていく必要があります。詳細については、「 [SQL から NoSQL へ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SQLtoNoSQL.html)」を参照してください。

 **実装計画に必要な工数レベル:** 高 

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

 **関連するベストプラクティス:** 
+  [REL03-BP02 特定のビジネスドメインと機能に重点を置いたサービスを構築する](rel_service_architecture_business_domains.md) 

 **関連するドキュメント:** 
+  [Amazon API Gateway: OpenAPI を使用した REST API の設定](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html) 
+  [サービス指向アーキテクチャとは](https://aws.amazon.com/what-is/service-oriented-architecture/) 
+  [境界付けられたコンテキスト (ドメイン駆動設計の中心的なパターン)](https://martinfowler.com/bliki/BoundedContext.html) 
+  [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  [マイクロサービスのトレードオフ](https://martinfowler.com/articles/microservice-trade-offs.html) 
+  [Microservices - a definition of this new architectural term](https://www.martinfowler.com/articles/microservices.html) 
+  [AWS でのマイクロサービス](https://aws.amazon.com/microservices/) 
+  [AWS App Mesh とは](https://docs.aws.amazon.com/app-mesh/latest/userguide/what-is-app-mesh.html) 

 **関連する例:** 
+  [Iterative App Modernization Workshop](https://catalog.us-east-1.prod.workshops.aws/workshops/f2c0706c-7192-495f-853c-fd3341db265a/en-US/intro) 

 **関連動画:** 
+  [Delivering Excellence with Microservices on AWS](https://www.youtube.com/watch?v=otADkIyugzY) 

# REL03-BP02 特定のビジネスドメインと機能に重点を置いたサービスを構築する
<a name="rel_service_architecture_business_domains"></a>

 サービス指向アーキテクチャ (SOA) は、ビジネスニーズに合わせて明確に定義された機能を備えたサービスを構築します。マイクロサービスはドメインモデルと境界付けられたコンテキストを使用してこれをさらに制限し、各サービスが 1 つのことだけを実行するようにします。特定の機能に焦点を当てることで、さまざまなサービスの信頼性要件を差別化し、より具体的に的を絞って投資することができます。簡潔なビジネス上の問題と各サービスに関連付けられた小さなチームにより、組織のスケーリングも容易になります。 

 マイクロサービスアーキテクチャを設計する際は、ドメイン駆動設計 (DDD) を使用して、エンティティでビジネス上の問題をモデル化すると便利です。例えば、Amazon.com ウェブサイトの場合、エンティティには、パッケージ、配送、スケジュール、料金、割引、通貨などがあります。その後、モデルは [https://martinfowler.com/bliki/BoundedContext.html](https://martinfowler.com/bliki/BoundedContext.html)、そこで類似した機能と属性を共有するエンティティがグループ化されます。したがって、Amazon.com の例で言うと、パッケージ、配送、スケジュールは発送コンテキストの一部となり、料金、割引、通貨は料金コンテキストの一部となります。モデルをコンテキストに分割したら、マイクロサービスを境界で区切る方法のテンプレートが現れます。 

![\[マイクロサービスを境界で区切る方法のモデルテンプレート\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/2022-03-31/framework/images/building-services.png)


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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  ビジネスドメインとそれぞれの機能に基づいてワークロードを設計します。特定の機能に焦点を当てることで、さまざまなサービスの信頼性要件を差別化し、より具体的に的を絞って投資することができます。簡潔なビジネス上の問題と各サービスに関連付けられた小さなチームにより、組織のスケーリングも容易になります。 
  +  ドメイン分析を実行して、ワークロードのドメイン駆動型設計 (DDD) をマッピングします。次に、ワークロードのニーズを満たすアーキテクチャタイプを選択できます。
    +  [モノリスをマイクロサービスに分割する方法](https://martinfowler.com/articles/break-monolith-into-microservices.html) 
    +  [レガシーシステムに囲まれているときの DDD の使用開始](https://domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf) 
    +  [Eric Evans “Domain-Driven Design: Tackling Complexity in the Heart of Software”](https://www.amazon.com/gp/product/0321125215) 
    +  [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+ サービスをできるだけ小さなコンポーネントに分解します。マイクロサービスアーキテクチャを使用すると、最小限の機能でワークロードをコンポーネントに分割し、全社的なスケーリングと俊敏性を実現できます。
  +  ワークロードの API とその設計目標、制約、使用に関するその他の検討事項を定義します。
    +  API を定義します。
      +  拡張と追加パラメータが実現可能になるように API を定義します。 
    +  設計時の可用性を定義します。
      + さまざまな機能に関して API の設計目標を複数立てることができます。
    +  制約を決める 
      +  テスティングを利用して、ワークロードの能力の上限を定義します。

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

 **関連するドキュメント:** 
+  [Amazon API Gateway: OpenAPI を使用した REST API の設定](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html) 
+  [境界付けられたコンテキスト (ドメイン駆動設計の中心的なパターン)](https://martinfowler.com/bliki/BoundedContext.html) 
+  [Eric Evans “Domain-Driven Design: Tackling Complexity in the Heart of Software”](https://www.amazon.com/gp/product/0321125215) 
+  [レガシーシステムに囲まれているときの DDD の使用開始](https://domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf) 
+  [モノリスをマイクロサービスに分割する方法](https://martinfowler.com/articles/break-monolith-into-microservices.html) 
+  [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  [マイクロサービスのトレードオフ](https://martinfowler.com/articles/microservice-trade-offs.html) 
+  [Microservices - a definition of this new architectural term](https://www.martinfowler.com/articles/microservices.html) 
+  [AWS でのマイクロサービス](https://aws.amazon.com/microservices/) 

# REL03-BP03 API ごとにサービス契約を提供する
<a name="rel_service_architecture_api_contracts"></a>

 サービス契約は、サービス統合に関するチーム間で文書化した合意で、機械で読み取ることができる API 定義、レート制限、パフォーマンスの期待値が含まれます。バージョニング戦略により、クライアントは既存の API を引き続き使用し、準備ができたらアプリケーションを新しい API に移行できます。契約に違反しない限り、デプロイはいつでも行うことができます。サービスプロバイダーチームは、選択した技術スタックを使用して、API 契約の条件を満たすことができます。同様に、サービスコンシューマーは独自のテクノロジーを使用できます。 

 マイクロサービスはサービス指向アーキテクチャ (SOA) という概念の進化形であり、マイクロサービスでは最小限の機能を備えたサービスを構築します。各サービスでは、サービスを使用するための API、設計目標、制限、その他の考慮事項が公開されています。これにより、アプリケーションの呼び出しを備えた *契約* が確立されます。これには次のような 3 つのメリットがあります。 
+  このサービスでは、対応すべきビジネスの課題が簡潔で、それを共有するチームの規模は小さくなります。これにより組織の拡大が可能となります。 
+  API の要件やその他の契約条件を満たしている限り、チームはいつでもデプロイできます。 
+  API の要件やその他の契約条件を満たしている限り、チームはあらゆる技術スタックを使用することができます。 

 Amazon API Gateway は、デベロッパーがあらゆる規模の API の作成、公開、保守、モニタリング、保護を簡単に行えるようにするためのフルマネージド型サービスです。Amazon API Gateway は、トラフィック管理、認可とアクセスコントロール、モニタリング、API バージョン管理など、最大数十万個の同時 API 呼び出しの受け入れと処理に伴うすべてのタスクを取り扱います。以前は Swagger 仕様として知られていた OpenAPI 仕様 (OAS) を使用して、API 契約を定義し、API Gateway にインポートできます。API Gateway を使用すると、API をバージョン管理してデプロイできます。 

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  API ごとにサービス契約を提供するサービス契約は、サービス統合に関するチーム間の文書化された合意であり、機械で読み取ることができる API 定義、レート制限、パフォーマンスの期待値が含まれます。 
  +  [Amazon API Gateway: OpenAPI を使用した REST API の設定](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html) 
    +  バージョニング戦略により、クライアントは既存の API を引き続き使用し、準備ができたらアプリケーションを新しい API に移行できます。
    +  Amazon API Gateway は、開発者が規模を問わず簡単に API を作成できる完全マネージド型サービスです。以前は Swagger 仕様として知られていた OpenAPI 仕様 (OAS) を使用して、API 契約を定義し、API Gateway にインポートできます。API Gateway を使用すると、API をバージョン管理してデプロイできます。

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

 **関連するドキュメント:** 
+  [Amazon API Gateway: OpenAPI を使用した REST API の設定](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html) 
+  [境界付けられたコンテキスト (ドメイン駆動設計の中心的なパターン)](https://martinfowler.com/bliki/BoundedContext.html) 
+  [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  [マイクロサービスのトレードオフ](https://martinfowler.com/articles/microservice-trade-offs.html) 
+  [Microservices - a definition of this new architectural term](https://www.martinfowler.com/articles/microservices.html) 
+  [AWS でのマイクロサービス](https://aws.amazon.com/microservices/) 

# REL 4 障害を防ぐために、分散システムでの操作をどのように設計すればよいですか?
<a name="w2aac19b9b7b7"></a>

分散システムは、サーバーやサービスなどのコンポーネントを相互接続するために通信ネットワークを利用しています。このネットワークでデータの損失やレイテンシーがあっても、ワークロードは確実に動作する必要があります。分散システムのコンポーネントは、他のコンポーネントやワークロードに悪影響を与えない方法で動作する必要があります。これらのベストプラクティスは、故障を防ぎ、平均故障間隔 (MTBF) を改善します。

**Topics**
+ [REL04-BP01 必要な分散システムの種類を特定する](rel_prevent_interaction_failure_identify.md)
+ [REL04-BP02 疎結合の依存関係を実装する](rel_prevent_interaction_failure_loosely_coupled_system.md)
+ [REL04-BP03 継続動作を行う](rel_prevent_interaction_failure_constant_work.md)
+ [REL04-BP04 すべての応答に冪等性を持たせる](rel_prevent_interaction_failure_idempotent.md)

# REL04-BP01 必要な分散システムの種類を特定する
<a name="rel_prevent_interaction_failure_identify"></a>

 ハードなリアルタイム分散システムでは、応答を同期的かつ迅速に行えるようにする必要がありますが、ソフトなリアルタイムシステムでは、応答に数分以上の余裕をもった時間枠があります。オフラインシステムは、バッチ処理または非同期処理を通じて応答を処理します。ハードなリアルタイム分散システムは、最も厳格な信頼性要件を持っています。 

 最も難しい [分散型システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) は、リクエスト / 応答サービスとも呼ばれるハードなリアルタイム分散システムです。それを困難にしているのは、リクエストが前触れもなく送信され、直ちに応答しなくてはならないという点です (お客様がレスポンスを待っているなど)。この例には、フロントエンドウェブサーバー、オーダーパイプライン、クレジットカードトランザクション、すべての AWS API、テレフォニーなどがあります。

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  必要な分散システムの種類を特定します。分散型システムの課題としては、レイテンシー、スケーリング、ネットワーキング API の理解、データのマーシャリングとアンマーシャリング、および Paxos などのアルゴリズムの複雑性に関するものがありました。システムが大きくなり、分散化が進むにつれて、理論上のエッジケースが日常的に発生するようになります。 
  +  [The Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
    +  ハードなリアルタイム分散システムでは、応答を同期的かつ迅速に与える必要があります。
    +  ソフトなリアルタイムシステムでは、応答に数分以上の余裕をもった時間枠があります。
    +  オフラインシステムは、バッチ処理または非同期処理を通じて応答を処理します。 
    +  ハードなリアルタイム分散システムは、最も厳格な信頼性要件を持っています。

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

 **関連するドキュメント:** 
+  [Amazon EC2: Ensuring Idempotency](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [The Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [The Amazon Builders' Library: 信頼性、動作の継続、一杯のコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [「Amazon EventBridge とは?」](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
+  [「Amazon Simple Queue Service とは何ですか?」](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) 

 **関連動画:** 
+  [AWS New York Summit 2019: Intro to Event-driven Architectures and Amazon EventBridge (MAD205)](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018: Close Loops and Opening Minds: How to Take Control of Systems, Big and Small ARC337 (疎結合、継続動作、静的安定性を含む)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019: Moving to event-driven architectures (SVS308)](https://youtu.be/h46IquqjF3E) 

# REL04-BP02 疎結合の依存関係を実装する
<a name="rel_prevent_interaction_failure_loosely_coupled_system"></a>

 キューイングシステム、ストリーミングシステム、ワークフロー、ロードバランサーなどの依存関係は、緩やかに結合しています。疎結合は、コンポーネントの動作をそれに依存する他のコンポーネントから分離するのに役立ち、弾力性と俊敏性を高めます。 

 1 つのコンポーネントを変更すると、それに依存する他のコンポーネントも強制的に変更される場合、それらは *緊密に* 結合されています。 *疎* 結合はこの依存関係を壊すため、依存コンポーネントが知る必要があるのは、バージョン管理されて公開されたインターフェイスのみです。依存関係があるコンポーネント間に疎結合を実装すると、あるコンポーネントの障害が別のコンポーネントに影響を及ぼさないようにすることができます。 

 疎結合により、そのコンポーネントに依存する他のコンポーネントのリスクを最小限に抑えながら、コンポーネントにコードまたは機能を自由に追加できます。また、スケールアウトしたり、依存関係の基盤となる実装を変更したりできるため、スケーラビリティが向上します。 

 疎結合によって弾力性をさらに向上させるには、可能な場合はコンポーネント間のやりとりを非同期にします。このモデルは、即時応答を必要とせず、リクエストが登録されていることの確認で十分な状況では、どのような対話にも最適です。イベントを生成するコンポーネントと、イベントを消費するコンポーネントがあります。2 つのコンポーネントは、直接的なポイントツーポイントのやりとりではなく、通常、SQS キューのような中間的な耐久性の高いストレージレイヤーや Amazon Kinesis のようなストリーミングデータプラットフォーム、または AWS Step Functions を介して統合されます。 

![\[キューイングシステムやロードバランサーなどの依存関係が疎結合されていることを示す図\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/2022-03-31/framework/images/loosely-coupled-dependencies.png)


 Amazon SQS キューと Elastic Load Balancing は、疎結合の中間レイヤーを追加する方法のうちの 2 つにすぎません。イベント駆動型アーキテクチャは、Amazon EventBridge を使用して AWS クラウド に構築することもできます。これにより、依存しているサービス (イベントコンシューマー) からクライアント (イベントプロデューサー) を抽出することができます。Amazon Simple Notification Service (Amazon SNS) は、高スループット、プッシュベースの多対多メッセージングが必要な場合に効果的なソリューションです。Amazon SNS トピックを使用すると、パブリッシャーシステムは、メッセージを多数のサブスクライバーエンドポイントにファンアウトして、並列処理できます。 

 キューにはいくつかの利点がありますが、ほとんどのハードリアルタイムシステムでは、しきい値の時間 (多くの場合、数秒) よりも長時間かかっているリクエストは古くなっていると見なされ (クライアントが停止し、応答を待機しなくなる)、処理されません。このように、古くなったリクエストの代わりに、より新しい (そしておそらくまだ有効な) リクエストを処理することができます。 

 **一般的なアンチパターン:** 
+  ワークロードの一部としてシングルトンをデプロイする。 
+  リクエストのフェイルオーバーや非同期処理を行うことはできない状態で、ワークロード層間で直接 API を呼び出す。 

 **このベストプラクティスを活用するメリット:** 疎結合は、コンポーネントの動作をそれに依存する他のコンポーネントから分離するのに役立ち、弾力性と俊敏性を高めます。1 つのコンポーネントの障害は他のコンポーネントから分離されます。 

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  疎結合の依存関係を実装します。キューイングシステム、ストリーミングシステム、ワークフロー、ロードバランサーなどの依存関係は、緩やかに結合しています。疎結合は、コンポーネントの動作をそれに依存する他のコンポーネントから分離するのに役立ち、弾力性と俊敏性を高めます。 
  +  [AWS re:Invent 2019: Moving to event-driven architectures (SVS308)](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
  +  [「Amazon EventBridge とは?」](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
  +  [「Amazon Simple Queue Service とは何ですか?」](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) 
    +  Amazon EventBridge では、疎結合で分散されたイベント駆動型アーキテクチャを構築できます
      +  [AWS New York Summit 2019: Intro to Event-driven Architectures and Amazon EventBridge (MAD205)](https://youtu.be/tvELVa9D9qU) 
    +  1 つのコンポーネントを変更すると、それに依存する他のコンポーネントも強制的に変更される場合、それらは密結合されています。疎結合はこの依存関係を壊すため、依存関係コンポーネントが知る必要があるのは、バージョン付きで公開されたインターフェイスのみです。
    +  可能な限り、コンポーネントのインタラクションを非同期にします。このモデルは、即時応答を必要とせず、要求が登録されていることの確認が十分である状況では、どのような対話にも最適です。
      +  [AWS re:Invent 2019: Scalable serverless event-driven applications using Amazon SQS and Lambda (API304)](https://youtu.be/2rikdPIFc_Q) 

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

 **関連するドキュメント:** 
+  [AWS re:Invent 2019: Moving to event-driven architectures (SVS308)](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
+  [Amazon EC2: 冪等性の確保](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [The Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [The Amazon Builders' Library: 信頼性、動作の継続、一杯のコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [「Amazon EventBridge とは?」](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
+  [「Amazon Simple Queue Service とは何ですか?」](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) 

 **関連動画:** 
+  [AWS New York Summit 2019: Intro to Event-driven Architectures and Amazon EventBridge (MAD205)](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018: Close Loops and Opening Minds: How to Take Control of Systems, Big and Small ARC337 (疎結合、継続動作、静的安定性を含む)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019: Moving to event-driven architectures (SVS308)](https://youtu.be/h46IquqjF3E) 
+  [AWS re:Invent 2019: Scalable serverless event-driven applications using Amazon SQS and Lambda (API304)](https://youtu.be/2rikdPIFc_Q) 

# REL04-BP03 継続動作を行う
<a name="rel_prevent_interaction_failure_constant_work"></a>

 負荷が急激に大きく変化すると、システム障害が発生することがあります。例えば、ワークロードで何千台ものサーバーのヘルスをモニタリングするヘルスチェックを実行する場合、毎回同じサイズのペイロード (現在の状態の完全なスナップショット) を送信しています。障害が発生しているサーバーがなくても、またはそのすべてに障害が発生していても、ヘルスチェックシステムは、大規模で急激な変更なしに常に作業を行っています。 

 たとえば、ヘルスチェックシステムが 100,000 台のサーバーをモニタリングしている場合、通常のサーバー障害率が軽いときは、その負荷はわずかです。ただし、重大なイベントによってこれらのサーバーの半分が異常な状態になると、ヘルスチェックシステムは、通知システムを更新し、クライアントに状態を通知しようとして過負荷になるでしょう。したがって、ヘルスチェックシステムは現在の状態の完全なスナップショットを毎回送信する必要があります。サーバー 100,000 台 のヘルス状態 (それぞれ 1 ビットで表される) のペイロードは、12.5 KB にすぎません。サーバーに障害が発生していないか、またはすべてに発生しているかにかかわらず、ヘルスチェックシステムは定期的に作業を行っているため、大規模の急激な変化はシステムの安定性を脅かすものではありません。これは実際に Amazon Route 53 がエンドポイントのヘルスチェック (IP アドレスなど) によってエンドユーザーがどのようにルーティングされているかを調べる際の方法です。 

 **このベストプラクティスが確立されていない場合のリスクレベル:** 低 

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  負荷が急激に変化してシステム障害が発生しないように、継続動作を行います。 
+  疎結合の依存関係を実装します。キューイングシステム、ストリーミングシステム、ワークフロー、ロードバランサーなどの依存関係は、緩やかに結合しています。疎結合は、コンポーネントの動作をそれに依存する他のコンポーネントから分離するのに役立ち、弾力性と俊敏性を高めます。 
  +  [The Amazon Builders' Library: 信頼性、動作の継続、一杯のコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
  +  [AWS re:Invent 2018: Close Loops and Opening Minds: How to Take Control of Systems, Big and Small ARC337 (ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法) ARC337 (継続動作を含む)](https://youtu.be/O8xLxNje30M?t=2482) 
    +  100,000 台のサーバーをモニタリングする健康診断システムの例の場合、成功または失敗の数に関係なく、ペイロードサイズが一定になるように、ワークロードを設計します。

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

 **関連するドキュメント:** 
+  [Amazon EC2: べき等性の確保](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [The Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [The Amazon Builders' Library: 信頼性、動作の継続、一杯のコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **関連動画:** 
+  [AWS New York Summit 2019: Intro to Event-driven Architectures and Amazon EventBridge (MAD205) (イベント駆動型アーキテクチャーと Amazon EventBridge 入門)](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018: Close Loops and Opening Minds: How to Take Control of Systems, Big and Small ARC337 (ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法) ARC337 (継続動作を含む)](https://youtu.be/O8xLxNje30M?t=2482) 
+  [AWS re:Invent 2018: Close Loops and Opening Minds: How to Take Control of Systems, Big and Small ARC337 (ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法) ARC337 (疎結合、継続動作、静的安定性を含む)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019: Moving to event-driven architectures (SVS308) (イベント駆動型アーキテクチャへの移行)](https://youtu.be/h46IquqjF3E) 

# REL04-BP04 すべての応答に冪等性を持たせる
<a name="rel_prevent_interaction_failure_idempotent"></a>

 べき等のサービスは、各リクエストが 1 回だけで完了することを約束します。そのため、同一のリクエストを複数回行っても、リクエストを 1 回行ったのと同じ効果しかありません。べき等サービスを使用すると、リクエストが誤って複数回処理されることを恐れる必要がなくなるため、クライアントが再試行を行いやすくなります。このために、クライアントはべき等性トークンを使用して API リクエストを発行できます。リクエストが繰り返される場合は常に同じトークンが使われます。べき等サービス API はトークンを使用して、リクエストが最初に完了したときに返された応答と同じ応答を返します。 

 分散システムでは、アクションを最大で 1 回 (クライアントがリクエストを 1 回だけ行う)、または少なくとも 1 回 (クライアントが成功を確認するまでリクエストを続ける) 実行するのは簡単です。ただし、アクションがべき等であることを保証することは困難です。つまり、 *正確に*  1 回だけ実行し、同一のリクエストを複数回行っても、リクエストを 1 回行うのと同じ効果を得るようにするということです。API でべき等性トークンを使用すると、サービスは、重複レコードや副作用を生むことなく、変更リクエストを 1 回または複数回受け取ることができます。 

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  すべての応答に冪等性を持たせます。べき等のサービスは、各リクエストが 1 回だけで完了することを約束します。そのため、同一のリクエストを複数回行っても、リクエストを 1 回行ったのと同じ効果しかありません。 
  +  クライアントはべき等性トークンを使用して API リクエストを発行できます。リクエストが繰り返される場合は常に同じトークンが使われます。べき等サービス API はトークンを使用して、リクエストが最初に完了したときに返された応答と同じ応答を返します。
    +  [Amazon EC2: 冪等性の確保](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 

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

 **関連するドキュメント:** 
+  [Amazon EC2: Ensuring Idempotency](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [The Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [The Amazon Builders' Library: 信頼性、動作の継続、一杯のコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **関連動画:** 
+  [AWS New York Summit 2019: Intro to Event-driven Architectures and Amazon EventBridge (MAD205)](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018: Close Loops and Opening Minds: How to Take Control of Systems, Big and Small ARC337 (疎結合、継続動作、静的安定性を含む)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019: Moving to event-driven architectures (SVS308)](https://youtu.be/h46IquqjF3E) 

# REL 5 障害を緩和または耐えるために、分散システムの操作をどのように設計しますか?
<a name="w2aac19b9b7b9"></a>

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

**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>

 コンポーネントの依存関係が異常な場合でも、コンポーネント自体は機能しますが、パフォーマンスが低下します。たとえば、依存関係の呼び出しが失敗した場合、事前に定義された静的レスポンスにフェイルオーバーします。 

 サービス A によって呼び出されたサービス B が、次にサービス C を呼び出すとします。 

![\[サービス B から呼び出されるとサービス C が失敗することを示す図。サービス B は、低下した応答をサービス A に返します。\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/2022-03-31/framework/images/graceful-degradation.png)


 サービス B がサービス C を呼び出すと、エラーまたはタイムアウトを受け取ります。サービス B は、サービス C (およびそれに含まれるデータ) からの応答がないため、返せるものを返します。これは、最後にキャッシュされた適切な値であるかもしれません。または、サービス B は、サービス C から受け取るはずだったものを所定の静的応答に置き換える可能性もあります。次に、低下した応答を呼び出し元のサービス A に返すことでしょう。この静的応答がない場合、サービス C で障害が発生すると、サービス B を介してサービス A にカスケードされ、可用性が失われます。 

 強い依存関係の可用性方程式の乗数的因子により (「 [https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/availability.html#dbedbedda68f9a15ACLX122](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/availability.html#dbedbedda68f9a15ACLX122)」を参照)、C の可用性が低下すると、B の有効な可用性に重大な影響を与えます。静的応答を返すことによりサービス B は、C での障害を軽減し、パフォーマンスが低下しますが、サービス C が 100% の可用性を実現しているように見せます (エラー条件下で確実に静的応答を返すと仮定します)。静的応答は単純にエラーを返す代わりに行う手段で、別の手段を使って応答を再計算する試みではないことに注意してください。まったく異なるメカニズムで同じ結果を達成しようとする試みは、フォールバック動作と呼ばれ、回避すべきアンチパターンです。 

 グレースフルデグラデーションのもう 1 つの例は *サーキットブレーカーパターン*.障害が一時的な場合は、再試行戦略を用いるのがよいでしょう。障害が一時的ではなく、操作が失敗する可能性が高い場合、サーキットブレーカーパターンは、失敗する可能性が高いリクエストをクライアントが実行できないようにします。リクエストが正常に処理されると、サーキットブレーカーは閉じられ、リクエストは正常に流されます。リモートシステムがエラーを返し始めるか、レイテンシーが高くなると、サーキットブレーカーが開かれ、依存関係が無視されるか、結果的に返される応答は単純に取得されたが包括的ではない応答 (単なる応答キャッシュである場合もあります) に置き換えられます。システムは、依存性が回復したかどうかを判断するために、依存関係を定期的に呼び出そうとします。依存関係が確認できたら、サーキットブレーカーは閉じられます。 

![\[サーキットブレーカーが開いた状態と閉じた状態を示した図。\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/2022-03-31/framework/images/circuit-breaker.png)


 図に示されている閉じた状態と開いた状態に加えて、開いた状態で設定可能な期間が経過すると、サーキットブレーカーは半分開いた状態に移行することもあります。この状態では、通常よりはるかに低いレートで定期的にサービスを呼び出そうとします。このプローブは、サービスの状態を確認するために使用します。半開状態で何度か成功すると、サーキットブレーカーは閉じた状態に移行し、通常のリクエストフローが再開されます。 

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  該当するハードな依存関係をソフトな依存関係に変換するため、グレイスフルデグラデーションを実装します。コンポーネントの依存関係が異常な場合でも、コンポーネント自体は機能しますが、パフォーマンスが低下します。たとえば、依存関係の呼び出しが失敗した場合、事前に定義された静的レスポンスにフェイルオーバーします。 
  +  静的応答を返すことで、ワークロードは依存関係で発生する障害を軽減します。
    +  [Well-Architected ラボ: レベル 300: ヘルスチェックを実装し依存関係を管理して、信頼性を向上する](https://wellarchitectedlabs.com/Reliability/300_Health_Checks_and_Dependencies/README.html) 
  +  再試行オペレーションが失敗する可能性がある場合を検出し、クライアントがサーキットブレーカーパターンで失敗した呼び出しを行わないようにします。
    +  [CircuitBreaker](https://martinfowler.com/bliki/CircuitBreaker.html) 

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

 **関連するドキュメント:** 
+  [Amazon API Gateway: スループット向上に向けた API リクエストのスロットリング](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [CircuitBreaker (「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) 
+  [The 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/) 

 **関連動画:** 
+  [再試行、バックオフ、ジッター: AWS re:Invent 2019: Introducing The Amazon Builders’ Library (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

 **関連する例:** 
+  [Well-Architected ラボ: レベル 300: ヘルスチェックを実装し依存関係を管理して、信頼性を向上する](https://wellarchitectedlabs.com/Reliability/300_Health_Checks_and_Dependencies/README.html) 

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

 リクエストのスロットリングは、予想外の需要の増加に対応するための軽減パターンです。一部のリクエストは受け入れられますが、定義された制限を超えるリクエストは拒否され、スロットルされたことを示すメッセージが返されます。クライアントの期待は、リクエストが戻されて放棄されるか、遅い速度で再試行することです。 

 サービスは、各ノードまたはセルが処理できる既知のリクエスト容量に合わせて設計する必要があります。この容量は、負荷テストによって設定できます。リクエストの到着率をトラッキングし、到着率が一時的に制限を超えると、リクエストが適切にスロットリングされたことを示す応答があります。これにより、ユーザーは、利用可能なキャパシティを持つ可能性のある別のノードまたはセルに再試行することができます。Amazon API Gateway には、リクエストをスロットリングするためのメソッドが用意されています。Amazon SQS と Amazon Kinesis はリクエストをバッファリングし、リクエスト率を平準化し、非同期で対応できるリクエストのスロットリングの必要性を軽減することができます。 

 **このベストプラクティスが確立されていない場合のリスクレベル:** 高 

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  リクエストをスロットリングします。これは、予想外の需要の増加に対応するための軽減パターンです。一部のリクエストは受け入れられますが、定義された制限を超えるリクエストは拒否され、スロットルされたことを示すメッセージが返されます。クライアントの期待は、リクエストが戻されて放棄されるか、遅い速度で再試行することです。 
  +  Amazon API Gateway を使用します。 
    +  [スループット向上に向けた API リクエストのスロットリング](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 

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

 **関連するドキュメント:** 
+  [Amazon API Gateway: スループット向上に向けた API リクエストのスロットリング](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [AWS でのエラー再試行とエクスポネンシャルバックオフ](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [The Amazon Builders' Library: 分散システムでのフォールバックの回避](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [The Amazon Builders' Library: 克服できないキューバックログの回避](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs) 
+  [The Amazon Builders' Library: タイムアウト、再試行、ジッターによるバックオフ](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 
+  [スループット向上に向けた API リクエストのスロットリング](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 

 **関連動画:** 
+  [Retry, backoff, and jitter (再試行、バックオフ、ジッター): AWS re:Invent 2019: Introducing The Amazon Builders’ Library (DOP328) (The Amazon Builders’ Library のご紹介)](https://youtu.be/sKRdemSirDM?t=1884) 

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

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

 分散ソフトウェアシステムの一般的なコンポーネントには、サーバー、ロードバランサー、データベース、DNS サーバーが含まれます。操作中に障害が発生すると、これらのコンポーネントのいずれかにエラーが発生し始める可能性があります。エラーを処理するデフォルトの手法は、クライアント側で再試行を行うことです。この手法により、アプリケーションの信頼性と可用性が向上します。ただし、再試行が大規模に行われた場合 (またエラーが発生してからすぐにクライアントが失敗した操作を再試行しようとすると)、ネットワークは、新しいリクエストと再試行されたリクエストですぐに飽和状態になり、それぞれがネットワーク帯域幅を奪い合うことになる可能性があります。これにより *再試行の大混乱が生じて、* サービスの可用性が低下します。このパターンは、システムが完全にダウンするまで続くかもしれません。 

 このようなシナリオを回避するには、一般的なエクスポネンシャルバックオフなどの *バックオフアルゴリズム* を使用する必要があります。エクスポネンシャルバックオフアルゴリズムは、再試行が行われる速度を徐々に下げて、ネットワークの輻輳を回避します。 

 多くの SDK およびソフトウェアライブラリ (AWS のものを含む) は、これらのアルゴリズムのバージョンを実装しています。ただし、 **バックオフアルゴリズムが存在することは想定しないでください。必ずこれをテストして検証してください。** 

 分散システムでは、すべてのクライアントが同時にバックオフし、再試行呼び出しのクラスターが発生する可能性があるため、単にバックオフするだけでは不十分です。Marc Brooker 氏のブログ記事「 [エクスポネンシャルバックオフとジッター](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-italics%0djitter/)は、エクスポネンシャルバックオフで wait() 関数を変更して、再試行呼び出しのクラスターを防ぐ方法を説明しています。解決策は、 *ジッター* を wait() 関数に追加することです。時間がかかり過ぎる再試行を行わないようにするには、実装ではバックオフを最大値に制限する必要があります。 

 最後に、 *再試行の最大数* または最大経過時間を設定し、これを超えると再試行が失敗するようにすることが重要です。AWS SDK はデフォルトでこれを実装しており、設定を変更することもできます。スタックの下位にあるサービスの場合、再試行の上限を 0 または 1 にするとリスクが緩和されますが、スタックの上位にあるサービスに再試行が委任されるため、効果的な方法です。 

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  再試行呼び出しを制御および制限します。エクスポネンシャルバックオフを使用して、徐々に長い間隔で再試行します。これらの再試行間隔をランダム化するジッターを導入し、再試行の最大数を制限します。 
  +  [AWS でのエラーの再試行とエクスポネンシャルバックオフ](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
    + Amazon SDK は、デフォルトで再試行とエクスポネンシャルバックオフを実装しています。お客様独自の依存サービスを呼び出す場合は、同類のロジックを依存関係レイヤーに実装します。タイムアウトの時間と、再試行をいつ停止するのかをユースケースに基づいて決めます。

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

 **関連するドキュメント:** 
+  [Amazon API Gateway: スループット向上に向けた API リクエストのスロットリング](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [AWS でのエラーの再試行とエクスポネンシャルバックオフ](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [The Amazon Builders' Library: 分散システムでのフォールバックの回避](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [The 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/) 

 **関連動画:** 
+  [再試行、バックオフ、ジッター: AWS re:Invent 2019: Introducing The Amazon Builders’ Library (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

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

 ワークロードがリクエストに正常に応答できない場合は、すぐに失敗するようにします。これにより、リクエストに関連付けられたリソースを解放でき、リソースが不足した場合にサービスを復旧できます。ワークロードは正常に応答できるが、リクエスト頻度が高すぎる場合は、代わりにキューを使用してリクエストをバッファします。ただし、長いキューは許可しないでください。クライアントがすでに処理を停止している古いリクエストを処理する原因となる可能性があるためです。 

 このベストプラクティスは、サーバー側、つまりリクエストのレシーバーに当てはまります。 

 キューはシステムの複数のレベルで作成される可能性があるため、応答が必要な新しいリクエストの前に (もはや応答を必要としない) 古い応答が処理されると、迅速に復旧する能力が著しく阻害される可能性があることに注意してください。キューがどこに存在するかに注意を払ってください。ワークフローや、データベースに記録された作業の中に隠れていることもよくあります。 

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  すぐに失敗し、キューを制限します。ワークロードがリクエストに正常に応答できない場合は、すぐに失敗するようにします。これにより、リクエストに関連付けられたリソースを解放でき、リソースが不足した場合にサービスを復旧できます。ワークロードは正常に応答できるが、リクエスト頻度が高すぎる場合は、代わりにキューを使用してリクエストをバッファします。ただし、長いキューは許可しないでください。クライアントがすでに処理を停止している古いリクエストを処理する原因となる可能性があるためです。 
  +  サービスへの負荷が過剰になったときのフェイルファストを実装します。
    +  [速やかな失敗](https://www.martinfowler.com/ieeeSoftware/failFast.pdf) 
  +  キューベースのシステムでは、処理が停止してもメッセージが到着し続けると、メッセージの負債が蓄積されて、大きなバックログになり、処理時間が長くなることがあります。作業の完了が遅すぎて、結果が役に立たなくなることがあります。これにより、基本的にキューイングが防御することを意図していた、可用性への悪影響が発生します。
    +  [The Amazon Builders' Library: 克服できないキューバックログの回避](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs) 

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

 **関連するドキュメント:** 
+  [AWS でのエラーの再試行とエクスポネンシャルバックオフ](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [速やかな失敗](https://www.martinfowler.com/ieeeSoftware/failFast.pdf) 
+  [The Amazon Builders' Library: 分散システムでのフォールバックの回避](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [The 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/) 

 **関連動画:** 
+  [再試行、バックオフ、ジッター: AWS re:Invent 2019: Introducing The Amazon Builders’ Library (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

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

 タイムアウトを適切に設定し、体系的に検証します。デフォルト値は通常高すぎるため、デフォルト値のままにしないでください。 

 このベストプラクティスは、クライアント側、つまりリクエストの送信者に当てはまります。 

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

 Amazon がタイムアウト、再試行、およびジッターによるバックオフを使用する方法について詳しくは  [https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/?did=ba_card&trk=ba_card](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/?did=ba_card&trk=ba_card). 

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  リモート呼び出しに接続タイムアウトとリクエストタイムアウトの両方を設定します。またこの設定は、プロセス全体のすべての呼び出しに一般的に行います。多くのフレームワークには組み込みのタイムアウト機能がありますが、その多くのデフォルト値は無限または高すぎるため、注意が必要です。値が高すぎると、クライアントがタイムアウトの発生を待機している間もリソースが消費され続けるため、タイムアウトの有用性が低下します。値が小さすぎると、再試行されるリクエストが多くなりすぎるため、バックエンドのトラフィックが増加し、レイテンシーが高くなってしまいます。場合によっては、すべてのリクエストが再試行されることになるため、完全な機能停止につながる恐れもあります。 
  +  [AWS SDK: 再試行とタイムアウト](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html) 

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

 **関連するドキュメント:** 
+  [AWS SDK: 再試行とタイムアウト](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html) 
+  [Amazon API Gateway: スループット向上に向けた API リクエストのスロットリング](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [AWS でのエラーの再試行とエクスポネンシャルバックオフ](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [The Amazon Builders' Library: タイムアウト、再試行、ジッターによるバックオフ](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 

 **関連動画:** 
+  [再試行、バックオフ、ジッター: AWS re:Invent 2019: Introducing The Amazon Builders’ Library (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

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

 サービスは、ステートを必要としないか、またはステートをオフロードして、異なるクライアントのリクエスト間で、ディスクやメモリのローカルに保存されたデータに依存しないようにする必要があります。これにより、可用性に影響を与えずにサーバーをいつでも交換できます。Amazon ElastiCache または Amazon DynamoDB は、オフロード状態の送信先として適しています。 

![\[このステートレスウェブアプリケーションでは、セッション状態は Amazon ElastiCache にオフロードされます。\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/2022-03-31/framework/images/stateless-webapp.png)


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

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

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

 **このベストプラクティスが確立されていない場合のリスクレベル:** ミディアム 

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  アプリケーションをステートレスにします。ステートレスアプリケーションは、水平方向へのスケーリングが可能であり、個別ノードのエラーに耐性があります。 
  +  リクエストパラメータに実際に格納できるステートを削除する
  +  ステートが必要かどうかを調べてから、あらゆるステート追跡を Amazon ElastiCache、Amazon RDS、Amazon DynamoDB などの回復力のあるマルチゾーンキャッシュやデータストア、またはサードパーティの分散データソリューションに移動します。移動できないステートをエラーに強いデータストアに格納します。
    +  一部のデータ (Cookie など) は、ヘッダーまたはクエリパラメータで渡すことができます。 
    +  リクエストですばやく渡すことができるステートを削除するためにリファクタリングします。
    +  実際には毎回のリクエストで必要のないデータはオンデマンドで取得できます。
    +  非同期で取得できるデータを削除します。
    +  必要なステートの条件を満たしているデータストアを決めます。 
    +  リレーショナル型ではないデータには NoSQL データベースを検討します。

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

 **関連するドキュメント:** 
+  [The Amazon Builders' Library: 分散システムでのフォールバックの回避](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [The 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/) 

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

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

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  緊急レバーを実装します。これは、ワークロードの可用性に対する影響を軽減できる可能性がある迅速なプロセスです。根本原因がなくても操作できます。緊急レバーは、完全に決定的なアクティブ化と非アクティブ化の基準を提供することにより、リゾルバーの認知負荷をゼロに減らせるものが理想的です。緊急レバーは多くの場合手動ですが、自動化することもできます 
  +  例えば、次のようなレバーがあります。 
    +  すべてのロボットトラフィックをブロックする 
    +  動的ページの代わりに静的ページを表示する 
    +  依存関係への呼び出しの頻度を減らす 
    +  依存関係からの呼び出しをスロットリングする 
  +  緊急レバーを実装して使用するためのヒント 
    +  緊急レバーがアクティブになったら、実行数を増やすのではなく、減らす 
    +  シンプルに保ち、バイモーダルな行動は避ける 
    +  緊急レバーを定期的にテストする 
  +  これらは、緊急レバーではないアクションの例です 
    +  キャパシティーを追加する 
    +  サービスに依存するクライアントのサービス所有者を呼び出して、呼び出しを減らすよう依頼する 
    +  コードを変更してリリースする 