

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

 信頼性の高いワークロードの実現は、ソフトウェアとインフラストラクチャの両方について事前に設計を決定することから始まります。アーキテクチャの選択は、Well-Architected の 6 つの柱のすべてにわたって、ワークロードの動作に影響を与えます。高い信頼性を保つには、特定のパターンに従う必要があります。

 次のセクションでは、高い信頼性を保つためにこのようなパターンで使用するベストプラクティスについて説明します。

**Topics**
+ [ワークロードサービスアーキテクチャを設計する](design-your-workload-service-architecture.md)
+ [障害を防ぐために分散システムでの操作を設計する](design-interactions-in-a-distributed-system-to-prevent-failures.md)
+ [障害を軽減するため、または障害に耐えるために分散システムでの相互作用を設計する](design-interactions-in-a-distributed-system-to-mitigate-or-withstand-failures.md)

# ワークロードサービスアーキテクチャを設計する
<a name="design-your-workload-service-architecture"></a>

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

 サービス指向アーキテクチャ (SOA) インターフェイスは一般的な通信標準を使用しているため、新しいワークロードに迅速に組み込むことができます。相互依存する分割不可能なユニットで構成されたモノリスアーキテクチャを構築するプラクティスは、SOA に置き替えられました。

 AWS では、長く SOA を使用してきましたが、現在はマイクロサービスを使用してシステムを構築しています。マイクロサービスには多くの魅力がありますが、可用性の点で重要なのは、マイクロサービスが小さくてシンプルであるということです。マイクロサービスでは、各種のサービスに求められる可用性を区別して、最も高い可用性ニーズを持つマイクロサービスに特化して投資を行うことができます。例えば、Amazon.com で製品情報ページ (「詳細ページ」) を配信するには、ページの個別の部分を作成するために何百ものマイクロサービスが呼び出されます。製品と料金の詳細を表示するために不可欠なサービスはいくつかありますが、そのサービスが利用できないときは、ページ上のコンテンツの大部分を単純に削除できます。顧客が製品を購入できる場合に、エクスペリエンスを提供するための写真やレビューなどは不要です。

**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/latest/reliability-pillar/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) 

 **関連する例:** 
+  [イテレーティブアプリモダナイゼーションワークショップ](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) は、ビジネスニーズに合わせて明確に定義された機能を備えたサービスを定義します。マイクロサービスは、ドメインモデルと制限付きコンテキストを使用して、ビジネスコンテキストの境界に沿ってサービスの境界を描きます。ビジネスドメインと機能に重点を置くことで、チームがサービスの独立した信頼性要件を定義しやすくなります。コンテキストに制限があると、ビジネスロジックが分離されてカプセル化されるため、チームは障害の処理方法について、より的確に判断できるようになります。

 **期待される成果:** エンジニアとビジネス関係者は共同で境界のあるコンテキストを定義し、それを使用して、特定のビジネス機能を果たすサービスとしてシステムを設計します。これらのチームは、イベントストーミングなどの確立された手法を使用して要件を定義します。新しいアプリケーションは、境界を明確に定義し、疎結合するサービスとして設計されます。既存のモノリスは[境界コンテキスト](https://martinfowler.com/bliki/BoundedContext.html)に分解され、システム設計は SOA またはマイクロサービスアーキテクチャに移行します。モノリスをリファクタリングする際には、バブルコンテキストやモノリスの分解パターンなどの確立されたアプローチが適用されます。

 ドメイン指向のサービスは、状態を共有しない 1 つ以上のプロセスとして実行されます。サービスは需要の変動に個別に対応し、ドメイン固有の要件に照らして障害シナリオを処理します。

 **一般的なアンチパターン:** 
+  チームは、特定のビジネスドメインではなく、UI や UX、ミドルウェア、データベースなどの特定の技術ドメインを中心に形成される。
+  アプリケーションがドメインの担当範囲にまたがっている。限定されたコンテキストにまたがるサービスは、メンテナンスが難しく、大規模なテスト作業が必要になり、複数のドメインチームがソフトウェア更新に参加する必要がある。
+  ドメインエンティティライブラリと同様に、ドメイン依存関係がサービス間で共有されるため、あるサービスドメインを変更すると、他のサービスドメインも変更する必要がある。
+  サービス契約とビジネスロジックはエンティティを共通かつ一貫したドメイン言語で表現していないため、翻訳層が発生し、システムが複雑になり、デバッグ作業が増加する。

 **このベストプラクティスを活用するメリット:** アプリケーションは、ビジネスドメインによって区切られた個別のサービスとして設計され、共通のビジネス言語を使用します。サービスは個別にテストおよびデプロイできます。サービスは、実装されたドメインのドメイン固有の回復力要件を満たします。

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

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

 ドメイン駆動型設計 (DDD) は、ビジネスドメインを中心にソフトウェアを設計および構築するための基本的なアプローチです。ビジネスドメインに焦点を当てたサービスを構築する際には、既存のフレームワークを使用すると便利です。既存のモノリシックアプリケーションを扱う場合は、確立された手法を提供する分解パターンを利用してアプリケーションをモダナイズし、サービスにすることができます。

![\[ドメイン駆動型設計のアプローチを示すフローチャート。\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/latest/reliability-pillar/images/domain-driven-decision.png)


 

## 実装手順
<a name="implementation-steps"></a>
+  チームは[イベントストーミング](https://serverlessland.com/event-driven-architecture/visuals/event-storming)ワークショップを開催して、軽量の付箋形式でイベント、コマンド、集計、ドメインをすばやく特定できます。
+  ドメインエンティティと関数がドメインコンテキストで形成されたら、[境界コンテキスト](https://martinfowler.com/bliki/BoundedContext.html)を使用してドメインをサービスに分割できます。境界コンテキストでは、類似の特徴と属性を共有するエンティティがグループ化されます。モデルをコンテキストに分割すると、マイクロサービスを境界で区切る方法のテンプレートが現れます。
  +  例えば、Amazon.com ウェブサイトエンティティには、パッケージ、配送、スケジュール、料金、割引、通貨などがあります。
  +  パッケージ、配送、スケジュールは出荷コンテキストにグループ化され、料金、割引、通貨は料金設定コンテキストにグループ化されます。
+  [モノリスをマイクロサービスに分解すると](https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-decomposing-monoliths/welcome.html)、マイクロサービスをリファクタリングするためのパターンが概説されます。ビジネス機能、サブドメイン、またはトランザクション別に分解するパターンを使用することは、ドメイン駆動のアプローチに適しています。
+  [バブルコンテキスト](https://www.domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf)などの戦術的な手法を使用すると、事前に書き直したり、DDD に全面的にコミットしたりすることなく、既存のアプリケーションまたはレガシーアプリケーションに DDD を導入できます。バブルコンテキストアプローチでは、サービスマッピングと調整、または新しく定義されたドメインモデルを外部の影響から保護する[破損防止層](https://serverlessland.com/event-driven-architecture/visuals/messages-between-bounded-context)を使用して、小さな境界コンテキストが確立されます。

 チームがドメイン分析を行い、エンティティとサービス契約を定義したら、AWS のサービスを活用し、ドメイン駆動型の設計をクラウドベースのサービスとして実装できます。
+  ドメインのビジネスルールを実践するテストを定義することから開発を始めましょう。テスト駆動型開発 (TDD) と動作駆動型開発 (BDD) は、チームがサービスをビジネス上の問題の解決に集中させるのに役立ちます。
+  ビジネスドメインの要件と[マイクロサービスアーキテクチャ](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/microservices-on-aws.html)に最適な [AWS のサービス](https://aws.amazon.com/microservices/)を選択します。
  +  [AWS サーバーレス](https://aws.amazon.com/serverless/)を使用すると、チームはサーバーやインフラストラクチャの管理ではなく、特定のドメインロジックに集中できます。
  +  [AWS のコンテナ](https://aws.amazon.com/containers/)を使用すると、インフラストラクチャの管理が簡素化されるため、ドメイン要件に集中できます。
  +  [目的別データベース](https://aws.amazon.com/products/databases/)は、ドメイン要件を最適なデータベースタイプに一致させるのに役立ちます。
+  [AWS にヘキサゴナルアーキテクチャを構築することで](https://docs.aws.amazon.com/prescriptive-guidance/latest/hexagonal-architectures/welcome.html)、ビジネスドメインから逆算してサービスにビジネスロジックを構築し、機能要件を満たして統合アダプターをアタッチするためのフレームワークの概要が示されます。インターフェイスの詳細と AWS のサービスのビジネスロジックを分離するパターンは、チームがドメインの機能に集中し、ソフトウェアの品質を向上させるのに役立ちます。

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

 **関連するベストプラクティス:** 
+  [REL03-BP01 ワークロードをセグメント化する方法を選択する](rel_service_architecture_monolith_soa_microservice.md) 
+  [REL03-BP03 API ごとにサービス契約を提供する](rel_service_architecture_api_contracts.md) 

 **関連ドキュメント:** 
+ [AWS マイクロサービス](https://aws.amazon.com/microservices/)
+  [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  [モノリスをマイクロサービスに分割する方法](https://martinfowler.com/articles/break-monolith-into-microservices.html) 
+  [レガシーシステムに囲まれているときの DDD の使用開始](https://domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf) 
+ [エリック・エヴァンスのドメイン駆動設計: ソフトウェアの核心にある複雑さに立ち向かう](https://www.amazon.com/gp/product/0321125215)
+ [AWS でヘキサゴナルアーキテクチャを構築する](https://docs.aws.amazon.com/prescriptive-guidance/latest/hexagonal-architectures/welcome.html)
+ [マイクロサービスへのモノリスの分解](https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-decomposing-monoliths/welcome.html)
+ [イベントストーミング](https://serverlessland.com/event-driven-architecture/visuals/event-storming)
+ [制限されたコンテキスト間のメッセージ](https://serverlessland.com/event-driven-architecture/visuals/messages-between-bounded-context)
+ [マイクロサービス](https://www.martinfowler.com/articles/microservices.html)
+ [テスト駆動型開発](https://en.wikipedia.org/wiki/Test-driven_development)
+ [動作駆動型開発](https://en.wikipedia.org/wiki/Behavior-driven_development)

 **関連する例:** 
+ [AWSでのクラウドネイティブマイクロサービスの設計 (DDD/EventStormingWorkshop より)](https://github.com/aws-samples/designing-cloud-native-microservices-on-aws/tree/main)

 **関連ツール**: 
+ [AWS クラウドデータベース](https://aws.amazon.com/products/databases/)
+ [AWS でのサーバーレス](https://aws.amazon.com/serverless/)
+ [AWS でのコンテナ](https://aws.amazon.com/containers/)

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

サービス契約とは、機械が読み取れる API 定義で定義された、API プロデューサーとコンシューマー間の文書化された契約です。契約バージョニング戦略により、コンシューマーは既存の API を引き続き使用し、準備ができたらアプリケーションを新しい API に移行できます。プロデューサーのデプロイは、契約がある限りいつでも行うことができます。サービスチームは、選択した技術スタックを使用して、API 契約の条件を満たすことができます。

 **期待される成果:** サービス指向またはマイクロサービスアーキテクチャで構築されたアプリケーションは、ランタイム依存関係を統合しながら独立して動作できます。API コンシューマーまたはプロデューサーに変更をデプロイしても、双方が共通の API 契約に従っていれば、システム全体の安定性が損なわれることはありません。サービス API を介して通信するコンポーネントは、相互にほとんど、またはまったく影響を与えずに、独立した機能リリース、ランタイム依存関係のアップグレード、またはディザスタリカバリ (DR) サイトへのフェイルオーバーを実行できます。さらに、ディスクリートサービスでは、他のサービスを一斉にスケールインしなくても、吸収するリソース需要を個別にスケールできます。

 **一般的なアンチパターン:** 
+  厳密に型指定されたスキーマを使用しないサービス API を作成します。その結果、API バインディングの生成に使用できない API や、プログラムで検証できないペイロードが生成されます。
+  バージョニング戦略を採用していないため、API コンシューマーに更新とリリースを強制します。または、サービス契約が進化するときに失敗します。
+  ドメインコンテキストや言語での統合の失敗を説明するのではなく、基盤となるサービス実装の詳細を漏らすエラーメッセージ。
+  API 契約を使用せずにテストケースを開発し、モック API 実装を使用しないことで、サービスコンポーネントを個別にテストできます。

 **このベストプラクティスを活用するメリット:** API サービス契約を介して通信するコンポーネントで構成された分散型システムでは、信頼性を向上させることができます。開発者は、コンパイル中にタイプチェックを行って、リクエストとレスポンスが API 契約に従っていること、および必須フィールドが存在することを確認し、開発プロセスの早期に潜在的な問題を発見できます。API 契約は、API 用のわかりやすい自己文書化インターフェイスを提供し、さまざまなシステムやプログラミング言語間の相互運用性を向上させます。

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

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

 ビジネスドメインを特定し、ワークロードのセグメント化を決定したら、サービス API を開発できます。まず、機械が読み取れる API のサービス契約を定義し、次に API バージョニング戦略を実装します。REST、GraphQL、非同期イベントなどの一般的なプロトコルでサービスを統合する準備ができたら、AWS のサービスをアーキテクチャに組み込み、コンポーネントを厳密に型指定された API 契約と統合できます。

 **サービス API 契約の AWS のサービス** 

 [Amazon API Gateway](https://aws.amazon.com/api-gateway/)、[AWS AppSync](https://aws.amazon.com/appsync/)、[Amazon EventBridge](https://aws.amazon.com/eventbridge/) などの AWS のサービスをアーキテクチャに組み込み、アプリケーションで API サービス契約を使用します。Amazon API Gateway は、ネイティブ AWS サービスやその他のウェブサービスと直接統合するのに役立ちます。API Gateway は、[OpenAPI 仕様](https://github.com/OAI/OpenAPI-Specification)とバージョニングをサポートしています。AWS AppSync は、クエリ、ミューテーション、サブスクリプションのサービスインターフェイスを定義する GraphQL スキーマを定義して設定する、マネージド [GraphQL](https://graphql.org/) エンドポイントです。Amazon EventBridge は、イベントスキーマを使用してイベントを定義し、イベントのコードバインディングを生成します。

## 実装手順
<a name="implementation-steps"></a>
+  まず、API の契約を定義します。契約では、API の機能を説明するだけでなく、API の入出力用に厳密に型指定されたデータオブジェクトとフィールドを定義します。
+  API Gateway で API を設定すると、エンドポイントの OpenAPI 仕様をインポートおよびエクスポートできます。
  +  [OpenAPI 定義をインポートすると](https://docs.aws.amazon.com/apigateway/latest/developerguide/import-edge-optimized-api.html)、API の作成が簡素化され、[AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/) や [AWS Cloud Development Kit (AWS CDK)](https://aws.amazon.com/cdk/) などのコードツールとしての AWS インフラストラクチャと統合できます。
  +  [API 定義をエクスポートすると](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html)、API テストツールとの統合が簡素化され、サービス利用者に統合仕様が提供されます。
+  AWS AppSync で [GraphQL スキーマファイルを定義して](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)、GraphQL API を定義して管理し、コントラクトインターフェイスを生成して、複雑な REST モデル、複数のデータベーステーブル、またはレガシー サービスとのやり取りを簡素化できます。
+  AWS AppSync と統合された [AWS Amplify](https://aws.amazon.com/amplify/) プロジェクトは、アプリケーションで使用するための厳密に型指定された JavaScript クエリファイルと、[Amazon DynamoDB](https://aws.amazon.com/dynamodb/) テーブル用の AWS AppSync GraphQL クライアントライブラリを生成します。
+  Amazon EventBridge からサービスイベントを利用する場合、イベントは、スキーマレジストリに既に存在するスキーマや OpenAPI 仕様で定義したスキーマに従います。レジストリでスキーマを定義すると、スキーマ契約からクライアントバインディングを生成して、コードをイベントと統合することもできます。
+  API の拡張またはバージョニング。オプションフィールドまたは必須フィールドのデフォルト値で構成できるフィールドを追加する場合、API を拡張する方が簡単なオプションです。
  +  REST や GraphQL などのプロトコルの JSON ベースの契約は、契約の拡張に適しています。
  +  SOAP のようなプロトコルの XML ベースの契約をサービスコンシューマーとテストして、契約拡張の可能性を判断する必要があります。
+  API をバージョニングするときは、ロジックを単一のコードベースで管理できるように、ファサードを使用してバージョンをサポートするプロキシバージョニングの実装を検討してください。
  +  API Gateway を使用すると、[リクエストとレスポンスのマッピング](https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html#transforming-request-response-body)を使用して、新しいフィールドにデフォルト値を提供したり、リクエストまたはレスポンスから削除されたフィールドを削除したりするファサードを確立し、契約の変更の吸収を簡素化できます。このアプローチにより、基盤となるサービスが単一のコードベースを維持できます。

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

 **関連するベストプラクティス:** 
+  [REL03-BP01 ワークロードをセグメント化する方法を選択する](rel_service_architecture_monolith_soa_microservice.md) 
+  [REL03-BP02 特定のビジネスドメインと機能に重点を置いたサービスを構築する](rel_service_architecture_business_domains.md) 
+  [REL04-BP02 疎結合の依存関係を実装する](rel_prevent_interaction_failure_loosely_coupled_system.md) 
+  [REL05-BP03 再試行呼び出しを制御および制限する](rel_mitigate_interaction_failure_limit_retries.md) 
+  [REL05-BP05 クライアントタイムアウトを設定する](rel_mitigate_interaction_failure_client_timeouts.md) 

 **関連ドキュメント:** 
+ [API (アプリケーションプログラミングインターフェイス) とは](https://aws.amazon.com/what-is/api/)
+ [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/microservices-on-aws.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/)
+ [OpenAPI への API Gateway 拡張機能の使用](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions.html)
+ [OpenAPI 仕様](https://github.com/OAI/OpenAPI-Specification)
+ [GraphQL: スキーマとタイプ](https://graphql.org/learn/schema/)
+ [Amazon EventBridge のコードバインディング](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-schema-code-bindings.html)

 **関連する例:** 
+ [Amazon API Gateway: OpenAPI を使用した REST API の設定](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html)
+ [Amazon API Gateway to Amazon DynamoDB CRUD application using OpenAPI](https://serverlessland.com/patterns/apigw-ddb-openapi-crud?ref=search)
+ [サーバーレス時代のモダンアプリケーション統合パターン: API Gateway サービスの統合](https://catalog.us-east-1.prod.workshops.aws/workshops/be7e1ee7-b91f-493d-93b0-8f7c5b002479/en-US/labs/asynchronous-request-response-poll/api-gateway-service-integration)
+ [Amazon CloudFront でのヘッダーベースの API Gateway バージョニングの実装](https://aws.amazon.com/blogs/compute/implementing-header-based-api-gateway-versioning-with-amazon-cloudfront/)
+ [AWS AppSync: クライアントアプリケーションをビルドする](https://docs.aws.amazon.com/appsync/latest/devguide/building-a-client-app.html#aws-appsync-building-a-client-app)

 **関連動画:** 
+ [ Using OpenAPI in AWS SAM to manage API Gateway ](https://www.youtube.com/watch?v=fet3bh0QA80)

 **関連ツール**: 
+ [Amazon API Gateway](https://aws.amazon.com/api-gateway/)
+ [AWS AppSync](https://aws.amazon.com/appsync/)
+ [Amazon EventBridge](https://aws.amazon.com/eventbridge/)

# 障害を防ぐために分散システムでの操作を設計する
<a name="design-interactions-in-a-distributed-system-to-prevent-failures"></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>

 分散システムには、同期、非同期、またはバッチの 3 つの種類があります。同期システムは、リクエストを可能な限り迅速に処理し、HTTP/S、REST、またはリモートプロシージャコール (RPC) プロトコルを使用して同期リクエスト呼び出しと応答呼び出しを行うことで相互に通信する必要があります。非同期システムは、個々のシステムを結合することなく、中間サービスを介して非同期的にデータを交換することによって相互に通信します。バッチシステムは大量の入力データを受け取り、人の介入なしに自動データプロセスを実行し、出力データを生成します。

 **望ましい結果:** 同期、非同期、バッチの依存関係と効果的に相互作用するワークロードを設計します。

 **一般的なアンチパターン:** 
+  ワークロードは依存関係からの応答を無期限に待つため、リクエストが受信されたかどうかが不明なまま、ワークロードクライアントがタイムアウトすることがあります。
+  ワークロードは、相互に同期呼び出しを行う一連の依存システムを使用しています。これには、チェーン全体で正常に処理が行われる前に、各システムが利用可能な状態にあり、システムでリクエストを正常に処理する必要があるため、動作が脆弱になり、全体的な可用性が損なわれる可能性があります。
+  ワークロードは依存関係と非同期で通信し、重複したメッセージを受信する場合が多いのにもかかわらず、1 回のみのメッセージ処理が保証されるという概念に基づいています。
+  適切なバッチスケジューリングツールを使用していないため、ワークロードは同じバッチジョブを同時に実行します。

 **このベストプラクティスを活用する利点:** 特定のワークロードでは、同期、非同期、バッチのいずれかの通信スタイルを 1 つ以上実装するのが一般的です。このベストプラクティスは、それぞれの通信スタイルに関連するさまざまなトレードオフを特定し、ワークロードが依存関係の中断に耐えられるようにするのに役立ちます。

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

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

 以下のセクションでは、各種類の依存関係に関する一般的な実装ガイダンスと固有の実装ガイダンスの両方について説明します。

 **一般的な質問、または機能要望** 
+  依存関係が提供するパフォーマンスと信頼性のサービスレベル目標 (SLO) が、ワークロードのパフォーマンスと信頼性の要件を満たしていることを確認します。
+  [AWS オブザーバビリティサービス](https://aws.amazon.com/cloudops/monitoring-and-observability)を使用して[応答時間とエラー率をモニタリング](https://www.youtube.com/watch?v=or7uFFyHIX0)し、依存関係がワークロードに必要なレベルでサービスを提供していることを確認します。
+  依存関係と通信する際に、ワークロードが直面する可能性のある課題を特定します。分散システムには、アーキテクチャの複雑さ、運用上の負担、コストが増加する可能性のある[さまざまな課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/)があります。一般的な課題には、レイテンシー、ネットワークの中断、データ損失、スケーリング、データ複製の遅延などがあります。
+  堅牢なエラー処理と[ログ記録](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html)を実装して、依存関係で問題が発生した場合の問題のトラブルシューティングに役立ててください。

 **同期依存関係** 

 同期通信では、ワークロードは依存関係にリクエストを送信し、応答を待っている操作をブロックします。依存関係がリクエストを受け取ると、すぐに処理を試み、応答をワークロードに送り返します。同期通信の大きな課題は、一時的な結合が発生するため、ワークロードとその依存関係を同時に利用できるようにする必要があることです。ワークロードで依存関係との同期通信が必要な場合は、以下のガイダンスを検討します。
+  ワークロードが 1 つの機能を実行するために複数の同期依存関係に依存するべきではありません。リクエストを正常に完了させるためにパス内のすべての依存関係が利用可能である必要があるため、依存関係の連鎖は全体的な脆弱性を高めます。
+  依存関係が正常でない場合や利用できない場合のエラー処理と再試行戦略を決定します。バイモーダル動作の使用は避けてください。バイモーダル動作とは、通常モードと障害モードでワークロードが異なる動作を示す場合をいいます。バイモーダル動作の詳細については、「[REL11-BP05 静的安定性を使用してバイモーダル動作を防止する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_withstand_component_failures_static_stability.html)」を参照してください。
+  ワークロードを待機させるより、フェイルファストの方がよいことを覚えておいてください。例えば、「[AWS Lambda デベロッパーガイド](https://docs.aws.amazon.com/lambda/latest/dg/invocation-retries.html)」では、Lambda 関数を呼び出すときに再試行や失敗を処理する方法について説明します。
+  ワークロードが依存関係を呼び出す際のタイムアウトを設定します。これにより、応答を待つ時間が長すぎたり、無期限に待ったりすることを回避できます。このトピックに関する役立つ説明は、「[レイテンシーを考慮した Amazon DynamoDB アプリケーションのための AWS Java SDK HTTP リクエスト設定のチューニング](https://aws.amazon.com/blogs/database/tuning-aws-java-sdk-http-request-settings-for-latency-aware-amazon-dynamodb-applications/)」に記載されています。
+  1 つのリクエストを処理するためのワークロードから依存関係への呼び出し回数を最小限に抑えます。呼び出し回数の多さは、結合とレイテンシーの増加につながります。

 **非同期依存関係** 

 ワークロードを依存関係から一時的に切り離すには、非同期で通信する必要があります。非同期アプローチを使用すると、ワークロードの依存関係や一連の依存関係からの応答の送信を待つことなく、他の処理を実行できます。

 ワークロードで依存関係との非同期通信が必要な場合は、以下のガイダンスを検討します。
+  ユースケースと要件に基づいて、メッセージングとイベントストリーミングのどちらを使用するかを決定します。[メッセージング](https://aws.amazon.com/messaging/)を使用すると、メッセージブローカーを介してメッセージを送受信することで、ワークロードが依存関係と通信できます。[イベントストリーミング](https://aws.amazon.com/streaming-data/)を使用すると、ワークロードとその依存関係は、ストリーミングサービスを使用して、できるだけ早く処理する必要のあるデータを継続的なストリームとして配信されるイベントを公開およびサブスクライブできます。
+  メッセージングとイベントストリーミングではメッセージの処理方法が異なるため、以下に基づいてトレードオフを決定する必要があります。
  +  **メッセージ優先度:** メッセージブローカーは、通常のメッセージよりも先に優先度の高いメッセージを処理できます。イベントストリーミングでは、すべてのメッセージの優先度が同じになります。
  +  **メッセージ消費:** メッセージブローカーは、コンシューマーがメッセージを受信したかどうか確認します。イベントストリーミングのコンシューマーは、最後に読んだメッセージを常に把握しておく必要があります。
  +  **メッセージの順序:** メッセージングでは、先入れ先出し (FIFO) アプローチを使用しない限り、メッセージの送信順序を正確に受信することは保証されません。イベントストリーミングでは、データが生成された順序が常に保持されます。
  +  **メッセージの削除:** メッセージングでは、コンシューマーはメッセージを処理した後に削除する必要があります。イベントストリーミングサービスはメッセージをストリームに追加し、メッセージの保存期間が終了するまでストリームに残ります。この削除ポリシーにより、イベントストリーミングはメッセージの再生に適したものになります。
+  依存関係がいつ作業を完了したかをワークロードがどのように認識するかを定義します。ワークロードが [Lambda 関数を非同期的](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html)に呼び出すと、Lambda はリクエストをキューに入れ、追加情報を含まない成功のレスポンスを返します。処理が完了すると、Lambda 関数は成功または失敗に基づいて設定可能な[送信先に結果を送信](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#invocation-async-destinations)できます。
+  べき等性を活用して、重複メッセージを処理するワークロードを構築します。べき等性とは、同じメッセージに対してワークロードが複数回生成されても、ワークロードの結果は変化しないことを指します。ネットワーク障害が発生した場合、または確認応答が受信されていない場合、[メッセージング](https://aws.amazon.com/sqs/faqs/#FIFO_queues)サービスまたは[ストリーミング](https://docs.aws.amazon.com/streams/latest/dev/kinesis-record-processor-duplicates.html)サービスがメッセージを再配信することに注意してください。
+  ワークロードが依存関係から応答を受け取らない場合は、ワークロードはリクエストを再送信します。リトライ回数を制限して、ワークロードの CPU、メモリ、ネットワークリソースの消費を抑え、他のリクエストを処理できるようにすることを検討してください。「[AWS Lambda ドキュメント](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#invocation-async-errors)」では、非同期呼び出しのエラーを処理する方法を示しています。
+  適切なオブザーバビリティ、デバッグ、トレースツールを活用して、ワークロードの非同期通信とその依存関係を管理し運用します。[Amazon CloudWatch](https://aws.amazon.com/cloudwatch/) を使用して、[メッセージング](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-available-cloudwatch-metrics.html)および[イベントストリーミング](https://docs.aws.amazon.com/streams/latest/dev/monitoring-with-cloudwatch.html)サービスをモニタリングできます。また、[AWS X-Ray](https://aws.amazon.com/xray/) を使用してワークロードを計測し、問題のトラブルシューティングに関する[インサイトをすばやく得る](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html)こともできます。

 **バッチ依存関係** 

 バッチシステムは、手動操作なしで、入力データを受け取り、処理するための一連のジョブを開始し、いくつかの出力データを生成します。データサイズにもよりますが、ジョブは数分から、場合によっては数日かかることもあります。ワークロードで依存関係とのバッチ通信を行う場合は、以下のガイダンスを検討します。
+  ワークロードでバッチジョブを実行する時間枠を定義します。ワークロードでは、例えば 1 時間ごとまたは月末に、バッチシステムを呼び出す繰り返しパターンを設定できます。
+  データ入力と処理済みデータ出力の場所を定義します。[Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/)、[Amazon Elastic File System (Amazon EFS)](https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html)、[Amazon FSx for Lustre ](https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html)などのストレージサービスを使用すると、大規模なワークロードのファイル読み書きに対応できます。
+  ワークロードで複数のバッチジョブを呼び出す必要がある場合は、[AWS Step Functions](https://aws.amazon.com/step-functions/?step-functions.sort-by=item.additionalFields.postDateTime&step-functions.sort-order=desc) を活用して、AWS またはオンプレミスで実行されるバッチジョブのオーケストレーションを簡素化できます。この[サンプルプロジェクト](https://github.com/aws-samples/aws-stepfunction-complex-orchestrator-app)は、Step Functions、[AWS Batch](https://aws.amazon.com/batch/)、および Lambda を使用したバッチジョブのオーケストレーションを示しています。
+  バッチジョブをモニタリングして、ジョブの完了に本来よりも時間がかかっているなどの異常がないかを確認します。[CloudWatch Container Insights](https://docs.aws.amazon.com/batch/latest/userguide/cloudwatch-container-insights.html) などのツールを使用して、AWS Batch 環境やジョブをモニタリングできます。この場合、ワークロードによって次のジョブの開始が停止し、関連するスタッフに例外が通知されます。

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

 **関連ドキュメント:** 
+  [AWS クラウド Operations: モニタリングとオブザーバビリティ](https://aws.amazon.com/cloudops/monitoring-and-observability) 
+  [Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [REL11-BP05 静的安定性を使用してバイモーダル動作を防止する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_withstand_component_failures_static_stability.html) 
+  [AWS Lambda デベロッパーガイド: AWS Lambda でのエラー処理と自動再試行](https://docs.aws.amazon.com/lambda/latest/dg/invocation-retries.html) 
+  [レイテンシーを考慮した Amazon DynamoDB アプリケーションのための AWS Java SDK HTTP リクエスト設定のチューニング](https://aws.amazon.com/blogs/database/tuning-aws-java-sdk-http-request-settings-for-latency-aware-amazon-dynamodb-applications/) 
+  [AWS メッセージング](https://aws.amazon.com/messaging/) 
+  [ストリーミングデータとは](https://aws.amazon.com/streaming-data/) 
+  [AWS Lambda デベロッパーガイド: 非同期呼び出し](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html) 
+  [Amazon Simple Queue Service に関するよくある質問: FIFO キュー](https://aws.amazon.com/sqs/faqs/#FIFO_queues) 
+  [Amazon Kinesis Data Streams デベロッパーガイド: 重複レコードの処理](https://docs.aws.amazon.com/streams/latest/dev/kinesis-record-processor-duplicates.html) 
+  [Amazon Simple Queue Service デベロッパーガイド: Amazon SQS で使用できる CloudWatch メトリクス](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-available-cloudwatch-metrics.html) 
+  [Amazon Kinesis Data Streams デベロッパーガイド: Amazon CloudWatch による Amazon Kinesis Data Streams Service のモニタリング](https://docs.aws.amazon.com/streams/latest/dev/monitoring-with-cloudwatch.html) 
+  [AWS X-Ray デベロッパーガイド: AWS X-Rayの概念](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html) 
+  [GitHub の AWS サンプル: AWS Step Functions 複雑なオーケストレーターアプリ](https://github.com/aws-samples/aws-stepfunction-complex-orchestrator-app) 
+  [AWS Batch ユーザーガイド: AWS Batch CloudWatch Container Insights](https://docs.aws.amazon.com/batch/latest/userguide/cloudwatch-container-insights.html) 

 **関連動画:** 
+  [AWS Summit SF 2022 - AWS によるフルスタックのオブザーバビリティとアプリケーションモニタリング (COP310)](https://www.youtube.com/watch?v=or7uFFyHIX0) 

 **関連ツール**: 
+  [Amazon CloudWatch](https://aws.amazon.com/cloudwatch/) 
+  [Amazon CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html) () 
+  [AWS X-Ray](https://aws.amazon.com/xray/) 
+  [Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) 
+  [Amazon Elastic File System (Amazon EFS)](https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html) 
+  [Amazon FSx for Lustre](https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html) 
+  [AWS Step Functions](https://aws.amazon.com/step-functions/?step-functions.sort-by=item.additionalFields.postDateTime&step-functions.sort-order=desc) 
+  [AWS Batch](https://aws.amazon.com/batch/) 

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

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

 キューイングシステム、ストリーミングシステム、ワークフローなどの依存関係を疎結合化すると、システムへの変更や障害の影響を最小限に抑えることができます。疎結合化により、コンポーネントの動作が依存する他のシステムに影響を与えないように分離され、回復力と俊敏性が向上します。

 密結合のシステムでは、あるコンポーネントを変更すると、そのコンポーネントに依存する他のコンポーネントも変更しなければならなくなり、結果として、すべてのコンポーネントのパフォーマンスが低下する可能性があります。疎結合はこの依存関係を壊すため、依存コンポーネントが知る必要があるのは、バージョン管理されて公開されたインターフェイスのみです。依存関係があるコンポーネント間に疎結合を実装すると、あるコンポーネントの障害が別のコンポーネントに影響を及ぼさないように隔離することができます。

 疎結合では、コードの変更やコンポーネントへの機能の追加を自由にできる一方で、そのコンポーネントに依存する他のコンポーネントへのリスクを最小限に抑えることができます。また、回復力を細分化でき、コンポーネントレベルでスケールアウトしたり、依存関係の根本的な実装さえも変更したりできます。

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

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


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

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

 **期待される成果:** 疎結合の依存関係を実装すると、コンポーネントレベルへの障害の面積を最小限に抑えることができ、問題の診断と解決に役立ちます。また、開発サイクルが簡素化され、チームはモジュールレベルで変更を実装できるようになり、その部分に依存する他のコンポーネントのパフォーマンスに影響は及びません。このアプローチでは、リソースのニーズに基づいてコンポーネントレベルでスケールアウトできるだけでなく、コスト効率良くコンポーネントを活用できるようになります。

 **一般的なアンチパターン:** 
+  モノリシックワークロードのデプロイ。
+  リクエストのフェイルオーバーや非同期処理を行うことはできない状態で、ワークロード層間で直接 API を呼び出す。
+  共有データを使用した密結合。疎結合のシステムでは、共有データベースや他の形で密結合されたデータストレージを介したデータの共有を避ける必要があります。そうしたデータ共有が密結合を持ち込み、スケーラビリティを妨げる可能性があります。
+  バックプレッシャーを無視する。ワークロードには、コンポーネントが同じ速度でデータを処理できない場合に、データの受信を遅らせたり停止したりする機能が必要です。

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

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

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

 疎結合の依存関係を実装します。疎結合のアプリケーションを構築するためのさまざまなソリューションがあります。フルマネージド型のキュー、自動化されたワークフロー、イベントへの対応、API などを実装するサービスがこれに当たりますが、いずれも、コンポーネントの動作を他のコンポーネントから隔離するのに役立ち、弾力性と俊敏性を高めます。
+  **イベント駆動型アーキテクチャの構築:** [Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) は、疎結合で分散されたイベント駆動型アーキテクチャの構築に役立ちます。
+  **分散システムにキューを実装する:** [Amazon Simple Queue Service (Amazon SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) を使用して、分散システムを統合および疎結合化できます。
+  **コンポーネントをマイクロサービスとしてコンテナ化:** [マイクロサービス](https://aws.amazon.com/microservices/)を使用すると、チームは十分に定義された API を通して通信する小型の独立コンポーネントから構成されるアプリケーションを構築できます。[Amazon Elastic Container Service (Amazon ECS)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html) および [Amazon Elastic Kubernetes Service (Amazon EKS)](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html) は、コンテナ化をすばやく実現できます。
+  **Step Functions を使用してワークフローを管理する:** [Step Functions](https://aws.amazon.com/step-functions/getting-started/) は、複数の AWS サービスを柔軟なワークフローに調整するのに役立ちます。
+  **パブリッシュ/サブスクライブ (pub/sub) メッセージングアーキテクチャを活用する:** [Amazon Simple Notiﬁcation Service (Amazon SNS)](https://docs.aws.amazon.com/sns/latest/dg/welcome.html) は、パブリッシャーからサブスクライバー (プロデューサーおよびコンシューマーとも呼ばれます) へのメッセージ配信を提供します。

### 実装手順
<a name="implementation-steps"></a>
+  イベント駆動型アーキテクチャのコンポーネントは、イベントによって開始されます。イベントは、ユーザーがカートに商品を追加するなど、システム内で発生するアクションです。アクションが正常に実行されると、システムの次のコンポーネントを起動するイベントが生成されます。
  + [ Amazon EventBridge を使用したイベント駆動型アプリケーションの構築 ](https://aws.amazon.com/blogs/compute/building-an-event-driven-application-with-amazon-eventbridge/)
  + [AWS re:Invent 2022: Amazon EventBridge を使用したイベント駆動型統合の設計 ](https://www.youtube.com/watch?v=W3Rh70jG-LM)
+  分散型メッセージングシステムには、キューベースのアーキテクチャを確立するために主に 3 つの部分を実装する必要があります。これには、分散型システムのコンポーネント、分離のために使用するキュー (Amazon SQS サーバー上で分散される)、キュー内のメッセージが該当します。一般的なシステムには、キューへのメッセージ配信を開始するプロデューサーと、キューからメッセージを受信するコンシューマーがあります。キューは、冗長性を確保するために、複数の Amazon SQS サーバーにメッセージを格納します。
  + [ Amazon SQS の基本的なアーキテクチャ](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-architecture.html)
  + [ Amazon Simple Queue Service を使用して分散アプリケーション間でメッセージを送信する ](https://aws.amazon.com/getting-started/hands-on/send-messages-distributed-applications/)
+  マイクロサービスをうまく利用すれば、疎結合のコンポーネントが独立したチームによって管理されるため、保守性とスケーラビリティが向上します。また、変更が必要になっても、動作を分離し、単一のコンポーネントに限定できます。
  + [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/microservices-on-aws.html)
  + [Let's Architect\$1 コンテナを使用するマイクロサービスの設計 ](https://aws.amazon.com/blogs/architecture/lets-architect-architecting-microservices-with-containers/)
+  AWS Step Functions では、分散型アプリケーションの構築、プロセスの自動化、マイクロサービスのオーケストレーションなどを行うことができます。複数のコンポーネントをオーケストレーションして 1 つのワークフローとしてまとめ、自動化することで、アプリケーション内の依存関係を分離できます。
  + [AWS Step Functions と AWS Lambda を使用してサーバーレスワークフローを作成する](https://aws.amazon.com/tutorials/create-a-serverless-workflow-step-functions-lambda/)
  + [AWS Step Functions の開始方法](https://aws.amazon.com/step-functions/getting-started/)

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

 **関連ドキュメント:** 
+  [Amazon EC2: べき等性を保証する](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library: 信頼性、動作の継続、1 杯のおいしいコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [What Is 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) 
+ [ モノリスから卒業する ](https://pages.awscloud.com/break-up-your-monolith.html)
+ [AWS Step Functions および Amazon SQS を使用してキューベースのマイクロサービスをオーケストレーションする ](https://aws.amazon.com/tutorials/orchestrate-microservices-with-message-queues-on-step-functions/)
+ [ Amazon SQS の基本的なアーキテクチャ ](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-architecture.html)
+ [ キューベースのアーキテクチャ ](https://docs.aws.amazon.com/wellarchitected/latest/high-performance-computing-lens/queue-based-architecture.html)

 **関連動画:** 
+  [AWS New York Summit 2019: イベント駆動型アーキテクチャと Amazon EventBridge 入門 (MAD205)](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018: ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法 ARC337 (疎結合、継続動作、静的安定性を含む)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019: イベント駆動型アーキテクチャへの移行 (SVS308)](https://youtu.be/h46IquqjF3E) 
+ [AWS re:Invent 2019: Amazon SQS と Lambda を使用するスケーラブルなサーバーレスイベント駆動型アプリケーション ](https://www.youtube.com/watch?v=2rikdPIFc_Q)
+ [AWS re:Invent 2022: Amazon EventBridge を使用したイベント駆動型統合の設計 ](https://www.youtube.com/watch?v=W3Rh70jG-LM)
+ [AWS re:Invent 2017: Elastic Load Balancing の詳細とベストプラクティス ](https://www.youtube.com/watch?v=9TwkMMogojY)

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

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

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

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

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  負荷が急激に変化してシステム障害が発生しないように、継続動作を行います。
+  疎結合の依存関係を実装します。キューイングシステム、ストリーミングシステム、ワークフロー、ロードバランサーなどの依存関係は、疎結合されています。疎結合は、コンポーネントの動作をそれに依存する他のコンポーネントから分離するのに役立ち、弾力性と俊敏性を高めます。
  +  [Amazon Builders' Library: 信頼性、動作の継続、1 杯のおいしいコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
  +  [AWS re:Invent 2018: ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法 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) 
+  [Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library: 信頼性、動作の継続、1 杯のおいしいコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **関連動画:** 
+  [AWS New York Summit 2019: イベント駆動型アーキテクチャと Amazon EventBridge 入門 (MAD205)](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018: ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法 ARC337 (継続動作を含む)](https://youtu.be/O8xLxNje30M?t=2482) 
+  [AWS re:Invent 2018: ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法 ARC337 (疎結合、継続動作、静的安定性を含む)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019: イベント駆動型アーキテクチャへの移行 (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 回または複数回受け取ることができます。

 **期待される成果:** すべてのコンポーネントとサービスにわたってべき等性を保証するための、一貫性があり、十分に文書化され、広く採用されているアプローチが得られます。

 **一般的なアンチパターン:** 
+  必要でない場合でも、無差別にべき等性を適用している。
+  べき等性を実装するための過度に複雑なロジックを導入している。
+  タイムスタンプは、べき等性のキーとして使用している。これにより、クロックスキューや、複数のクライアントが同じタイムスタンプを使用して変更を適用することが原因で、不正確さが生じる可能性があります。
+  べき等性を保つためにペイロード全体を保存している。このアプローチでは、リクエストごとに完全なデータペイロードを保存し、新しいリクエストごとに上書きします。これにより、パフォーマンスが低下し、スケーラビリティに影響する可能性があります。
+  サービス間でキーの生成に一貫性がない。一貫したキーがないと、サービスは重複するリクエストを認識しない可能性があり、意図しない結果になる可能性があります。

 **このベストプラクティスを活用するメリット:** 
+  スケーラビリティの向上: システムは、追加のロジックや複雑な状態管理を実行することなく、再試行や重複したリクエストを処理できます。
+  信頼性の向上: べき等性により、サービスは複数の同一リクエストを一貫した方法で処理できるようになり、予期しない副作用や重複レコードのリスクが軽減されます。これは、ネットワーク障害や再試行が頻繁に発生する分散システムでは特に重要です。
+  データ整合性の向上: 同じリクエストが同じレスポンスを生成するため、べき等性は分散システム間でデータ整合性を維持するのに役立ちます。これは、トランザクションとオペレーションの整合性を維持するために不可欠です。
+  エラー処理: べき等性トークンを使用すると、エラー処理がより簡単になります。問題によりクライアントが応答を受信しなかった場合、同じべき等性トークンを使用してリクエストを安全に再送信できます。
+  運用上の透明性: べき等性を使用すると、モニタリングとログ記録が向上します。サービスは、べき等性トークンを使用してリクエストをログに記録できるため、問題の追跡とデバッグが容易になります。
+  API 契約の簡素化: クライアント側とサーバー側のシステム間の契約を簡素化し、誤ったデータ処理が行われる恐れを軽減します。

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

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

 分散システムでは、アクションを最大 1 回 (クライアントは 1 つのリクエストのみを行う) または少なくとも 1 回 (クライアントは成功が確認されるまでリクエストを続ける) 実行するのは比較的簡単です。ただし、*確実に 1 回だけ*動作を実装するのは困難です。これを実現するには、クライアントはリクエストごとにべき等性トークンを生成して提供する必要があります。

 べき等性トークンを使用することによって、サービスは新しいリクエストと繰り返しのリクエストを区別できます。サービスがべき等性トークンを含むリクエストを受信すると、そのトークンが既に使用されているかどうかが確認されます。トークンが使用されている場合、サービスは保存されたレスポンスを取得して返します。トークンが新しい場合、サービスはリクエストを処理し、レスポンスをトークンと共に保存し、レスポンスを返します。このメカニズムにより、すべてのレスポンスがべき等になり、分散システムの信頼性と一貫性が向上します。

 べき等性は、イベント駆動型アーキテクチャの重要な動作でもあります。これらのアーキテクチャは通常、Amazon SQS、Amazon MQ、Amazon Kinesis Streams、Amazon Managed Streaming for Apache Kafka (MSK) などのメッセージキューによってサポートされます。状況によっては、1 回だけ公開されたメッセージが誤って複数回配信されることがあります。パブリッシャーがべき等性トークンを生成してメッセージに含める場合、受信した重複メッセージの処理によって、同じメッセージに対するアクションが繰り返されないように要求します。コンシューマーは受信した各トークンを追跡し、重複したトークンを含むメッセージを無視する必要があります。

 サービスとコンシューマーは、受信したべき等性トークンを、呼び出すダウンストリームサービスにも渡す必要があります。同様に、処理チェーン内のすべてのダウンストリームサービスは、メッセージを複数回処理することの副作用を避けるために、べき等性が実装されていることを確認する責任があります。

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

1.  **べき等性オペレーションを特定する** 

    どのオペレーションにべき等性が必要かを判断します。通常、これには POST、PUT、DELETE HTTP メソッドとデータベースの挿入、更新、または削除オペレーションが含まれます。読み取り専用クエリなど、状態を変更しない操作では、副作用がない限り、通常はべき等性は必要ありません。

1.  **一意の識別子を使用する** 

    送信者から送信される各べき等オペレーションのリクエストには、リクエストに直接、またはメタデータ (HTTP ヘッダーなど) の一部として、一意のトークンを含めます。これにより、受信者は重複するリクエストやオペレーションを認識して処理できます。トークンに一般的に使用される識別子には、[Universally Unique Identifiers (UUID)](https://datatracker.ietf.org/doc/html/rfc9562) と [K-Sortable Unique Identifiers (KSUID)](https://github.com/segmentio/ksuid) があります。

1.  **状態の追跡と管理** 

    ワークロード内の各オペレーションまたはリクエストの状態を維持します。これは、べき等性トークンと対応する状態 (保留中、完了、失敗など) をデータベース、キャッシュ、またはその他の永続的ストアに保存することによって実現できます。この状態情報により、ワークロードは重複するリクエストやオペレーションを識別して処理できます。

    必要に応じて、ロック、トランザクション、オプティミスティック同時実行コントロールなどの適切な同時実行コントロールメカニズムを使用して、一貫性と原子性を維持します。これには、べき等性トークンを記録し、リクエストの処理に関連するすべての変更操作を実行するプロセスが含まれます。これにより、競合状態を防ぎ、べき等操作が正しく実行されることを確認できます。

    ストレージとパフォーマンスを管理するために、データストアから古いべき等性トークンを定期的に削除します。ストレージシステムがサポートしている場合は、データの有効期限タイムスタンプ (有効期限または TTL 値とも呼ばれます) の使用を検討してください。べき等性トークンの再利用の可能性は時間の経過と共に減少します。

    べき等性トークンと関連する状態を保存するために通常使用される一般的な AWS ストレージオプションは次のとおりです。
   +  **Amazon DynamoDB**: DynamoDB は、低レイテンシーのパフォーマンスと高可用性を提供する NoSQL データベースサービスであり、べき等性関連データの保存に最適です。DynamoDB のキー値およびドキュメントデータモデルにより、べき等性トークンと関連する状態情報を効率的に保存および取得できます。また、アプリケーションが挿入時に TTL 値を設定すると、DynamoDB はべき等性トークンを自動的に期限切れにすることもできます。
   +  **Amazon ElastiCache**: ElastiCache は、高スループット、低レイテンシー、低コストでべき等性トークンを保存できます。ElastiCache (Redis) と ElastiCache (Memcached) の両方とも、アプリケーションが挿入時に TTL 値を設定すると、べき等性トークンを自動的に期限切れにすることもできます。
   +  **Amazon Relational Database Service (RDS):** 特にアプリケーションが他の目的でリレーショナルデータベースを既に使用している場合は、Amazon RDS を使用してべき等性トークンと関連する状態情報を保存できます。
   +  **Amazon Simple Storage Service (S3):** Amazon S3 は、べき等性トークンと関連メタデータの保存に使用できる、スケーラビリティと耐久性の高いオブジェクトストレージサービスです。S3 のバージョニング機能は、べき等操作の状態を維持するのに特に役立ちます。ストレージサービスの選択は、通常、べき等性関連データの量、必要なパフォーマンス特性、耐久性と可用性の必要性、べき等性メカニズムが全体的なワークロードアーキテクチャとどのように統合されるかなどの要因によって決まります。

1.  **べき等性オペレーションを実装する** 

    API とワークロードコンポーネントをべき等になるように設計します。べき等性チェックをワークロードコンポーネントに組み込みます。リクエストを処理する前、またはオペレーションを実行する前に、一意の識別子が既に処理されているかどうかを確認します。存在する場合は、オペレーションを再度実行する代わりに、前の結果を返します。例えば、クライアントがユーザーの作成リクエストを送信した場合、同じ一意の識別子を持つユーザーが既に存在するかどうかを確認します。ユーザーが存在する場合は、新しいユーザー情報を作成する代わりに、既存のユーザー情報を返す必要があります。同様に、キューコンシューマーが重複したべき等性トークンを含むメッセージを受信した場合、コンシューマーはそのメッセージを無視する必要があります。

    リクエストのべき等性を検証する包括的なテストスイートを作成します。成功したリクエスト、失敗したリクエスト、重複したリクエストなど、幅広いシナリオをカバーする必要があります。

    ワークロードが AWS Lambda 関数を活用する場合は、AWS Lambda の Powertools を検討してください。Powertools for AWS Lambda は、サーバーレスのベストプラクティスを実装し、AWS Lambda 関数を操作する際のデベロッパーの速度を向上させるデベロッパーツールキットです。特に、Lambda 関数を再試行しても安全なべき等操作に変換するユーティリティを提供します。

1.  **べき等性を明確に伝える** 

    API とワークロードコンポーネントをドキュメント化して、操作のべき等性を明確に伝えます。これにより、クライアントは予想される動作と、ワークロードと確実にやり取りする方法を理解できます。

1.  **モニタリングと監査** 

    モニタリングと監査のメカニズムを実装して、予期しないレスポンスの変動や過剰な重複リクエストの処理など、レスポンスのべき等性に関連する問題を検出します。これにより、ワークロードの問題や予期しない動作を検出して調査できます。

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

 **関連するベストプラクティス:** 
+  [REL05-BP03 再試行呼び出しを制御および制限する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_mitigate_interaction_failure_limit_retries.html) 
+  [REL06-BP01 ワークロードのすべてのコンポーネントをモニタリングする (生成)](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_monitor_aws_resources_monitor_resources.html) 
+  [REL06-BP03 通知を送信する (リアルタイム処理とアラーム)](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_monitor_aws_resources_notification_monitor.html) 
+  [REL08-BP02 デプロイの一部として機能テストを統合する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_tracking_change_management_functional_testing.html) 

 **関連ドキュメント:** 
+  [The Amazon Builders' Library: Making retries safe with idempotent APIs](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/) 
+  [Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library: 信頼性、動作の継続、1 杯のおいしいコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [Amazon Elastic Container Service: Ensuring idempotency](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/ECS_Idempotency.html) 
+  [Lambda 関数をべき等にするにはどうすればよいですか?](https://repost.aws/knowledge-center/lambda-function-idempotent)
+  [Ensuring idempotency in Amazon EC2 API requests](https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-idempotency.html) 

 **関連動画:** 
+  [Building Distributed Applications with Event-driven Architecture - AWS Online Tech Talks](https://www.youtube.com/watch?v=gA2-eqDVSng&t=1668s) 
+  [AWS re:Invent 2023 - Building next-generation applications with event-driven architecture](https://www.youtube.com/watch?v=KXR17uwLEC8) 
+  [AWS re:Invent 2023 - Advanced integration patterns & trade-offs for loosely coupled systems](https://www.youtube.com/watch?v=FGKGdUiZKto) 
+  [AWS re:Invent 2023 - Advanced event-driven patterns with Amazon EventBridge ](https://www.youtube.com/watch?v=6X4lSPkn4ps) 
+  [AWS re:Invent 2018 - Close Loops and Opening Minds: How to Take Control of Systems, Big and Small ARC337 (includes loose coupling, constant work, static stability)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019 - Moving to event-driven architectures (SVS308)](https://youtu.be/h46IquqjF3E) 

 **関連ツール**: 
+  [Idempotency with AWS Lambda Powertools (Java)](https://docs.powertools.aws.dev/lambda/java/utilities/idempotency/) 
+  [Idempotency with AWS Lambda Powertools (Python)](https://docs.powertools.aws.dev/lambda/python/latest/utilities/idempotency/) 
+  [AWS Lambda Powertools GitHub page](https://github.com/aws-powertools/) 

# 障害を軽減するため、または障害に耐えるために分散システムでの相互作用を設計する
<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)