

# 工作負載架構
<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) 與微型服務組合而成。可以無狀態的工作負載較有能力部署為微型服務。 

 **預期成果：** 工作負載應可受支援、可擴展，並且盡可能地鬆散耦合。 

 在選擇如何劃分工作負載時，請在效益與複雜性之間取得平衡。讓新產品能率先推出的正確做法，不同於打造可從最初需求擴展的工作負載的做法。重構現有的整合型時，您必須考量應用程式如何能支援以無狀態為方向的解構。將服務細分為較小的服務，可讓明確定義的小型團隊加以開發及管理。但較小的服務可能會帶來複雜性，包括延遲可能增加、偵錯更複雜，以及運作負擔增加。 

 **常見的反模式：** 
+  AWS Well-Architected [微型服務 *Death Star*](https://mrtortoise.github.io/architecture/lean/design/patterns/ddd/2018/03/18/deathstar-architecture.html) 是一種特定情況：基本元件變得高度互相依賴，以致於只要有其中之一失敗，就會引發更加巨大的失敗，而導致元件像整合型一樣僵固且脆弱。

 **建立此實務準則的優勢：** 
+  更明確的劃分可造就更高的靈活性、組織彈性及可擴展性。 
+  降低服務中斷的影響。 
+  應用程式元件可能會有不同的可用性要求，這一點可藉由更細微的劃分來支應。 
+  為支援工作負載的團隊明確定義責任。 

 **未建立此最佳實務時的曝險等級：** 高 

## 實作指引
<a name="implementation-guidance"></a>

 根據劃分工作負載的方式，選擇您的架構類型。選擇 SOA 或微型服務架構 (或在少數情況下選擇整合型架構)。即使您選擇從整合型架構開始，仍須確保該架構為模組化，且隨著使用者採用，產品擴展時，該架構最終可以演進成 SOA 或微型服務。SOA 和微型服務各自提供較小的劃分，這些劃分同時也是偏好使用的現代可擴展且可靠的架構；但在部署微型服務架構時，特別要考慮做一些取捨。 

 主要取捨之一，就是您現在擁有一種分散式運算架構，而其可能會增加您滿足使用者延遲要求的難度，並且在偵測和追蹤使用者互動方面還存在額外的複雜性。您可以利用 AWS X-Ray 來解決此問題。要考慮的另一個影響是，隨著您管理的應用程式數量增加，營運複雜性也隨之增加，因而需要部署多個獨立元件。 

![\[整合型、服務導向與微型服務架構的比較圖\]](http://docs.aws.amazon.com/zh_tw/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) 
+  [微型服務 - 此新架構術語的定義](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) 

 **相關影片：** 
+  [透過 AWS 上的微型服務提供卓越品質](https://www.youtube.com/watch?v=otADkIyugzY) 

# REL03-BP02 建置專注於特定業務領域和功能的服務
<a name="rel_service_architecture_business_domains"></a>

 服務導向架構 (SOA) 會建置具有依業務需求定義之明確描述功能的服務。微型服務運用領域模型和有界限的環境來對此項業務進一步限縮，因此各服務僅做一件事。專注於特定功能讓您能夠區別不同服務的可靠性要求，並更集中瞄準投資目標。簡要的業務問題和與各服務相關的小型團隊，也更容易讓組織擴展。 

 在設計微型服務架構的過程中，運用領域驅動設計 (DDD) 有助於使用實體建立業務問題模型。例如，對於 Amazon.com 網站而言，實體可能包括包裝、交付、時間表、價格、折扣和貨幣。然後運用 [https://martinfowler.com/bliki/BoundedContext.html](https://martinfowler.com/bliki/BoundedContext.html)，將此模型進一步劃分成更小的模型，其中具有相似功能和特性的實體歸類成一組。因此，以 Amazon.com 為例，包裝、交付及時間表會是出貨環境的一環，而價格、折扣及貨幣則是定價環境的一環。隨著此模型劃分成多個環境，如何界定微型服務界限的範本便會浮現。 

![\[如何界定微型服務的模型範本\]](http://docs.aws.amazon.com/zh_tw/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「領域驅動設計：解決軟件核心的複雜性」](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「領域驅動設計：解決軟件核心的複雜性」](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) 
+  [微型服務 - 此新架構術語的定義](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 及使用該服務的設計目標、限制和其他考量事項。這可與 *呼叫應用程式* 建立合約。這樣即可實現三個主要優勢： 
+  該服務包含一個待處理的簡明業務問題，以及一個存在業務問題的小團隊。這樣一來，將能更好地進行組織擴展。 
+  只要符合 API 和合約要求，團隊能隨時進行部署。 
+  只要符合 API 和合約要求，團隊能隨時使用任何他們想要的技術堆疊。 

 Amazon API Gateway 是一項全受管的服務，可讓開發人員輕鬆地建立、發佈、維護、監控和保護任何規模的 API。涉及接受和處理多達數十萬個並行 API 呼叫 (包括流量管理、授權與存取控制、監控和 API 版本管理) 的所有任務均由 API Gateway 處理。您可以使用 OpenAPI Specification (OAS) (先前稱為 Swagger Specification)，定義 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。您可以使用 OpenAPI Specification (OAS) (先前稱為 Swagger Specification)，定義 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) 
+  [微型服務 - 此新架構術語的定義](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/) 也稱為請求/回覆服務。較困難的是，無法預測請求何時抵達，且必須快速回應 (例如，客戶正在主動等待回應)。範例包括前端 Web 伺服器、訂單管道、信用卡交易、每個 AWS API 和電話語音。

 **若未建立此最佳實務，暴露的風險等級：** 高 

## 實作指引
<a name="implementation-guidance"></a>
+  識別需要哪種分散式系統。分散式系統的挑戰包含延遲、擴展、了解聯網 API、資料編組和解編，以及 Paxos 等演算法的複雜性。隨著系統擴大並且益加分散，理論上的極端案例也變成經常發生的案例。 
  +  [Amazon Builders' Library：分散式系統的挑戰](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
    +  硬式即時分散式系統需要同步、快速給予回應。
    +  軟式即時系統則可以在更長的時段 (分鐘) 內來回應。
    +  離線系統會透過批次或非同步處理來處理回應。 
    +  硬式即時分散式系統具有最嚴格的可靠性要求。

## 資源
<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：可靠性、持續工作，以及咖啡時刻](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) 

 **相關影片：** 
+  [2019 年 AWS 紐約高峰會：事件驅動架構和 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) 

# REL04-BP02 實作鬆散耦合相依性
<a name="rel_prevent_interaction_failure_loosely_coupled_system"></a>

 佇列系統、串流系統、工作流程和負載平衡器之間具有鬆散耦合的相依性。鬆耦合有助於將某個元件的行為與依賴它的其他元件隔離，進而提高彈性和敏捷性。 

 如果一個元件的變更迫使依賴它的其他元件也變更，則屬於 *緊密* 耦合。 *鬆* 耦合會破壞此相依性，因此相依元件只需要知道受版本控制的和已發佈的界面。在相依性之間實作鬆耦合，可避免一個元件中的故障影響另一個元件。 

 鬆耦合可讓您將其他程式碼或功能新增至某個元件，同時將依賴該元件的其他元件的風險降至最低。此外，您可以向外擴展甚或變更相依性的基礎實作，因此可擴展性也會得到提升。 

 若要透過鬆耦合進一步改善彈性，請盡可能讓元件採用非同步互動。此模型適用於不需要立即回應的任何互動，以及確認已註冊請求便以足夠的狀況。它涉及產生事件的一個元件和取用事件的另一個元件。這兩個元件不會透過點對點直接互動來整合，但通常會透過中繼耐用儲存層來整合，例如 SQS 佇列，或如 Amazon Kinesis 或 AWS Step Functions 等串流資料平台。 

![\[圖表：顯示佇列系統和負載平衡器之間具有鬆散耦合的相依性。\]](http://docs.aws.amazon.com/zh_tw/wellarchitected/2022-03-31/framework/images/loosely-coupled-dependencies.png)


 Amazon SQS 佇列和 Elastic Load Balancer 只是為鬆耦合新增中繼層的兩種方式。事件驅動型架構也可以使用 Amazon EventBridge 在 AWS 雲端 建置。其可從用戶端依賴的服務 (事件消費者) 中抽取用戶端 (事件生產者)。當您需要高輸送量、推送架構的多對多傳訊時，Amazon Simple Notification Service (Amazon SNS) 是有效的解決方案。使用 Amazon SNS 主題，您的發佈者系統可以將訊息散發給大量訂閱者端點，以進行平行處理。 

 雖然佇列提供多項優勢，但在大多數硬式即時系統中，超過閾值時間 (通常為秒) 的請求應視為過時 (用戶端已放棄且不再等待回應) 且未處理。這樣才可以處理較新的 (且可能仍有效的) 請求。 

 **常用的反模式：** 
+  將單例部署為工作負載的一部分。 
+  在工作負載層之間直接叫用 API，沒有容錯移轉或非同步處理請求的功能。 

 **建立此最佳實務的優勢：** 鬆耦合有助於將某個元件的行為與依賴它的其他元件隔離，進而提高彈性和敏捷性。避免一個元件中的失敗影響其他元件。 

 **若未建立此最佳實務，暴露的風險等級：** 高 

## 實作指引
<a name="implementation-guidance"></a>
+  實作鬆散耦合相依性。佇列系統、串流系統、工作流程和負載平衡器之間具有鬆散耦合的相依性。鬆耦合有助於將某個元件的行為與依賴它的其他元件隔離，進而提高彈性和敏捷性。 
  +  [AWS re:Invent 2019：移至事件驅動架構 (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 可讓您建置鬆散耦合和分散式的事件驅動型架構。
      +  [2019 年 AWS 紐約高峰會：事件驅動架構和 Amazon EventBridge 簡介 (MAD205)](https://youtu.be/tvELVa9D9qU) 
    +  如果一個元件的變更迫使依賴它的其他元件也變更，則屬於緊密耦合。鬆耦合會破壞此相依性，因此相依元件只需要知道受版本控制的和已發佈的界面。
    +  盡可能讓元件採用非同步互動。此模型適用於不需要立即回應的任何互動，以及確認已註冊請求便以足夠的狀況。
      +  [AWS re:Invent 2019：使用 Amazon SQS 和 Lambda 的可擴展無伺服器事件驅動應用程式 (API304)](https://youtu.be/2rikdPIFc_Q) 

## 資源
<a name="resources"></a>

 **相關文件：** 
+  [AWS re:Invent 2019：移至事件驅動架構 (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) 
+  [Amazon Builders' Library：分散式系統的挑戰](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [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) 

 **相關影片：** 
+  [2019 年 AWS 紐約高峰會：事件驅動架構和 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 的可擴展無伺服器事件驅動應用程式 (API304)](https://youtu.be/2rikdPIFc_Q) 

# 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：可靠性、持續工作，以及咖啡時刻](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：可靠性、持續工作，以及咖啡時刻](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **相關影片：** 
+  [2019 年 AWS 紐約高峰會：事件驅動架構和 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>

 等冪服務承諾每個請求只完成一次，使得發出多個相同請求與發出單一請求具有相同的效果。等冪服務可讓用戶端更輕鬆地實作重試，而不用擔心錯誤地多次處理請求。為此，用戶端可以使用等冪權杖發出 API 請求，即每次重複請求時，都會使用相同的權杖。等冪服務 API 會使用權杖來傳回與第一次完成請求時傳回之回應相同的回應。 

 在分散式系統中，執行最多一次動作 (用戶端只發出一個請求) 或至少一次動作 (持續發出請求，直到用戶端確認成功) 很容易。但很難保證動作是等冪的，這表示它 *只執行一次，* 使得發出多個相同的請求與發出單一請求具有相同效果。透過在 API 中使用等冪性權杖，服務可以收到一次或多次變異請求，而不會產生重複的記錄或副作用。 

 **若未建立此最佳實務，暴露的風險等級：** 中 

## 實作指引
<a name="implementation-guidance"></a>
+  將所有回應設為等冪。等冪服務承諾每個請求只完成一次，使得發出多個相同請求與發出單一請求具有相同的效果。 
  +  用戶端可以使用等冪權杖發出 API 請求，即每次重複請求時，都會使用相同的權杖。等冪服務 API 會使用權杖來傳回與第一次完成請求時傳回之回應相同的回應。
    +  [Amazon EC2：確保等冪性](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 

## 資源
<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：可靠性、持續工作，以及咖啡時刻](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **相關影片：** 
+  [2019 年 AWS 紐約高峰會：事件驅動架構和 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) 

# 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/zh_tw/wellarchitected/2022-03-31/framework/images/graceful-degradation.png)


 當服務 B 呼叫服務 C 時，其會從服務 C 收到錯誤或逾時。缺少來自服務 C 回應 (及其包含的資料) 的服務 B，會傳回其所能執行的回應。這可能是上次快取的良好值，或者服務 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% (假設它在錯誤情況下可靠地傳回靜態回應)。請注意，靜態回應是傳回錯誤的簡單替代方法，並不會嘗試以不同方式重新計算回應。這種以完全不同的機制來嘗試達到相同結果的嘗試稱為備用行為，並且是一種可避免的反模式。 

 適度降級的另一個範例是 *斷路器模式*。當故障是暫時性時，應該使用重試策略。如果情況並非如此，且操作可能會失敗，則斷路器模式會阻止用戶端執行可能失敗的請求。在正常處理請求時，斷路器合閘，請求流過。當遠端系統開始傳回錯誤或出現高延遲時，斷路器會開啟，並忽略相依性，或是將結果取代為更輕鬆取得但不完整的回應 (可能只是回應快取)。系統會定期嘗試呼叫該相依性，以確定其是否已復原。發生這種情況時，斷路器將閉合。 

![\[圖表：顯示處於開啟和關閉狀態的斷路器。\]](http://docs.aws.amazon.com/zh_tw/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 設計和部署生產就緒型軟體」](https://pragprog.com/titles/mnee2/release-it-second-edition/) 
+  [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/) 
+  [Amazon Builders' Library：逾時、重試、退避與抖動](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 

 **相關影片：** 
+  [重試、退避和抖動：AWS re:Invent 2019：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) 
+  [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/timeouts-retries-and-backoff-with-jitter/) 
+  [調節 API 請求以獲得更佳的輸送量](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 

 **相關影片：** 
+  [重試、退避和抖動：AWS re:Invent 2019：Amazon Builders' Library 簡介 (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

# REL05-BP03 控制和限制重試呼叫
<a name="rel_mitigate_interaction_failure_limit_retries"></a>

 使用指數退避以在逐漸延長間隔後重試。引進抖動來隨機化這些重試間隔，並限制重試次數上限。 

 分散式軟體系統中的典型元件包括伺服器、負載平衡器、資料庫和 DNS 伺服器。在操作中，且操作可能失敗時，任何這些項目都可能開始產生錯誤。處理錯誤的預設技術是在用戶端實作重試。此技術可提高應用程式的可靠性和可用性。不過，如果用戶端在發生錯誤時立即嘗試重試失敗的操作，則網路很快就會因為新的和重試的請求而大規模地變得飽和，且每個請求都會爭奪網路頻寬。這可能會導致 *重試暴風，* 而該情況會降低服務的可用性。此模式可能會持續進行，直到整個系統出現故障為止。 

 若要避免這類情境，應該使用一般指數退避等 *退避演算法* 。指數退避演算法會逐漸降低執行重試的速率，從而避免網路擁塞。 

 許多開發套件和軟體程式庫 (包括來自 AWS 的程式庫) 都會實作這些演算法的一個版本。不過， **絕對不要假設退避演算法存在，請一律測試並驗證是否如此。** 

 單靠簡單退避是不夠的，因為在分散式系統中，所有用戶端都可能會同時退避，從而建立重試呼叫的叢集。Marc Brooker 在其部落格文章 [指數退避和抖動](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-italics%0djitter/)，說明了如何修改指數退避中的 wait () 函數，以防止重試呼叫的叢集。解決 *方法* 是在 wait() 函數中新增抖動。為避免重試太久，實作時應該將退避上限設為最大值。 

 最後，請務必設定 *最大重試次數* 或經過時間，之後重試就會失敗。AWS 開發套件預設情況下可實作此功能，並可以對其進行設定。對於堆疊中較低的服務，最大重試限制為零或一時可限制風險，但仍然有效，因為重試會委派給堆疊中較高的服務。 

 **若未建立此最佳實務，暴露的風險等級：** 高 

## 實作指引
<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) 
+  [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/) 
+  [Amazon Builders' Library：逾時、重試、退避與抖動](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 

 **相關影片：** 
+  [重試、退避和抖動：AWS re:Invent 2019：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) 
  +  限制佇列：在佇列式系統中，當處理停止但訊息持續送達時，待處理訊息可能大量積存，使得處理時間增加。工作可能太晚完成而無效，基本上會導致佇列要防範的可用性問題。
    +  [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) 
+  [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/) 
+  [Amazon Builders' Library：逾時、重試、退避與抖動](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 

 **相關影片：** 
+  [重試、退避和抖動：AWS re:Invent 2019：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) 
+  [Amazon Builders' Library：逾時、重試、退避與抖動](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 

 **相關影片：** 
+  [重試、退避和抖動：AWS re:Invent 2019：Amazon Builders' Library 簡介 (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

# REL05-BP06 盡可能讓服務無狀態
<a name="rel_mitigate_interaction_failure_stateless"></a>

 服務不應要求狀態，或應該卸載狀態，以便在不同的用戶端請求之間，不依賴磁碟上和記憶體中本機儲存的資料。這讓伺服器能夠任意置換，而不會對可用性造成影響。Amazon ElastiCache 或 Amazon DynamoDB 是卸載狀態的適當目的地。 

![\[在這個無狀態的 Web 應用程式中，工作階段狀態會卸載至 Amazon ElastiCache。\]](http://docs.aws.amazon.com/zh_tw/wellarchitected/2022-03-31/framework/images/stateless-webapp.png)


 當使用者或服務與應用程式互動時，他們通常會執行形成工作階段的一系列互動。工作階段是使用者在使用應用程式時，在不同請求之間持續存在的唯一資料。無狀態應用程式是一種不需要了解先前互動，也不會儲存工作階段資訊的應用程式。 

 一旦設計為無狀態，您就可以使用 AWS Lambda 或 AWS Fargate 等無伺服器運算服務。 

 除了伺服器替換，無狀態應用程式的另一個好處是它們可以水平擴展，因為任何可用的運算資源 (例如，EC2 執行個體和 AWS Lambda 函數) 都可以處理所有請求。 

 **若未建立此最佳實務，暴露的風險等級：** 中 

## 實作指引
<a name="implementation-guidance"></a>
+  讓您的應用程式無狀態。無狀態應用程式支援水平擴展，並且可以容忍單個節點的故障。 
  +  移除實際上可以儲存在請求參數中的狀態。
  +  在檢查了是否需要狀態之後，將狀態追蹤移至彈性多可用區域資料儲存，例如 Amazon ElastiCache、Amazon RDS、Amazon DynamoDB 或第三方分散式資料解決方案。儲存無法移動到彈性資料儲存的狀態。
    +  某些資料 (如 Cookie) 可以在標頭或查詢參數中傳遞。 
    +  重構以移除可以在請求中快速傳遞的狀態。
    +  某個請求可能實際上並不需要某些資料，這些資料可以隨需擷取。
    +  移除可以非同步擷取的資料。
    +  確定滿足所需狀態要求的資料儲存。 
    +  考慮將 NoSQL 資料庫用於非關聯式資料。

## 資源
<a name="resources"></a>

 **相關文件：** 
+  [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/) 

# REL05-BP07 實作緊急控制桿
<a name="rel_mitigate_interaction_failure_emergency_levers"></a>

 緊急控制桿是可緩解對工作負載的可用性影響的快速程序。 

 **若未建立此最佳實務，暴露的風險等級：** 中 

## 實作指引
<a name="implementation-guidance"></a>
+  實作緊急控制桿。這是可緩解對工作負載的可用性影響的快速程序。它們可以在沒有根本原因的情況下操作。理想的緊急控制桿會提供完全決定性啟用和停用準則，將解析器的認知負擔降至零。控制桿通常是手動的，但也可以自動化 
  +  範例控制桿包括 
    +  封鎖所有機器人流量 
    +  提供靜態頁面而非動態頁面 
    +  減少對相依性的呼叫頻率 
    +  調節來自相依性的呼叫 
  +  實作和使用緊急控制桿的秘訣 
    +  當啟用控制桿時，請少做，而非多做 
    +  保持簡單，避免雙模式行為 
    +  定期測試您的控制桿 
  +  以下是非緊急控制桿動作的範例 
    +  新增容量 
    +  呼叫依賴您服務的用戶端服務擁有者，並要求他們減少呼叫 
    +  變更程式碼並將其釋出 