

# 工作負載架構
<a name="workload-architecture"></a>

 可靠的工作負載始於對軟體和基礎設施的前期設計決策。您的架構選擇會對所有六大 Well-Architected 支柱的工作負載行為產生影響。為求可靠性，您必須依循特定模式。

 以下數節說明使用這些可靠性模式的最佳實務。

**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) 是一種特定情況：基本元件變得高度互相依賴，以致於只要有其中之一失敗，就會引發更加巨大的失敗，而導致元件像整合型一樣僵固且脆弱。

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

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

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

 根據劃分工作負載的方式，選擇您的架構類型。選擇 SOA或 微服務架構 （或在極少數情況下，選擇單片架構）。即使您選擇從整體架構開始，仍必須確保其為模組化，並隨著產品隨著使用者採用而擴展，最終可以發展為 SOA或 微服務。SOA 和 微服務分別提供較小的分割，這是現代可擴展且可靠的架構，但需要考慮權衡，特別是部署微服務架構時。

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

![\[整合型、服務導向與微型服務架構的比較圖\]](http://docs.aws.amazon.com/zh_tw/wellarchitected/latest/reliability-pillar/images/monolith-soa-microservices-comparison.png)


## 實作步驟
<a name="implementation-steps"></a>
+  決定適當的架構以重構或建置您的應用程式。SOA 和 微服務分別提供較小的分割，這是現代可擴展且可靠的架構首選。SOA 對於實現更小的分割，同時避免微服務的一些複雜性，可能是一個很好的妥協。如需詳細資訊，請參閱 [Microservice Trade-Offs](https://martinfowler.com/articles/microservice-trade-offs.html)。
+  如果您的工作負載適用於此類型，且您的組織可以提供支援，則應使用微型服務架構達成最佳的靈活性和可靠性。如需更多詳細資訊，請參閱在 [上實作 Microservices 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) 可充當增量重構的起點。如需詳細資訊，親參閱 [Seamlessly migrate on-premises legacy workloads using a strangler pattern](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) 可以在重新設計雲端中的舊版應用程式時，協助將差距橋接為服務匯流排。
+  對於具有單一共用資料庫的現有整合型，請選擇如何將資料重新組織為較小的區段。此時可以按業務單位、存取模式或資料結構來劃分。在重構程序中，您應該選擇使用關聯式或非關聯式 （否 SQL） 類型的資料庫繼續。如需更多詳細資訊，請參閱[從 SQL到否 SQL](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：RESTAPI使用 Open 設定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) 
+  [在 上實作 Microservices 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) 

 **相關影片：**
+  [在 上使用 Microservices 實現卓越 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 或微服務架構。整合型服務重構時，會套用已建立的方法 (如 Bubble 環境) 和整合型分解模式。

 領域導向服務會以一或多個不共用狀態的程序執行。它們會單獨回應需求的波動，並根據領域的特定要求來處理錯誤情境。

 **常見的反模式：**
+  團隊是依據特定技術領域 (例如 UI 和 UX、中介軟體或資料庫) 組成的，而不是特定的業務領域。
+  應用程式跨多個領域責任。跨有界限環境的服務可能更難以維護，需要較大量的測試工作，且需要多個領域團隊參與軟體更新。
+  領域相依性 (例如領域實體程式庫) 會跨服務共用，因此一個服務領域出現變更時，需要變更其他服務領域 
+  服務合約和商業邏輯無法以通用且一致的領域語言來表達實體，因此會導致翻譯層級使系統複雜化，並增加偵錯工作。

 **建立此最佳實務的優勢：**應用程式設計為獨立的服務，受到業務領域限制，並使用共同的商務語言。服務可以單獨測試和部署。服務符合實作領域的特定恢復能力要求。

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

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

 領域驅動設計 (DDD) 是依據業務領域設計和建置軟體的基礎方法。在建置專注於業務領域的服務時，使用現有架構將有所幫助。使用現有的整合型應用程式時，您可以利用分解模式提供已建立的技術，將應用程式現代化為服務。

![\[此流程圖描述領域驅動設計的方法。\]](http://docs.aws.amazon.com/zh_tw/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)概述了重構微型服務的模式。按業務功能、子領域或交易使用分解的模式，會與領域驅動的方法保持一致。
+  諸如 [bubble 環境](https://www.domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf)等戰術可讓您在現有或舊版應用程式中導入 DDD，而無須預先重寫和對 DDD 完整承諾。在 bubble 環境方法中，使用服務映射和協調或[防損毀層](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 Serverless](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消費者或生產者的變更不會中斷整體系統的穩定性。透過服務通訊的元件APIs可以執行獨立的功能版本、升級至執行時間相依性，或容錯移轉至災難復原 （DR） 站台，彼此幾乎沒有影響。此外，離散服務能夠獨立擴展而滿足資源需求，不需要其他服務一起擴展。

 **常見的反模式：**
+  建立APIs不含強烈輸入結構描述的服務。這會導致 APIs無法用來產生無法以程式設計方式驗證的API繫結和承載。
+  不採用版本控制策略，這會強制API消費者在服務合約演進時更新和發行或失敗。
+  錯誤訊息會透露基礎服務實作的詳細資訊，而不是說明領域環境和語言中的整合失敗。
+  不使用API合約來開發測試案例和模擬API實作，以允許獨立測試服務元件。

 **建立此最佳實務的好處：**由透過API服務合約通訊的元件組成的分散式系統可以提高可靠性。開發人員可以在開發程序的早期發現潛在的問題，並在編譯期間進行類型檢查，以確認請求和回應遵循API合約和必填欄位。API 合約為 APIs和 提供者提供了明確的自我記錄介面，讓不同的系統和程式設計語言之間具有更好的互通性。

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

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

 識別業務網域並確定工作負載分割後，您就可以開發服務 APIs。首先，定義 的機器可讀取服務合約APIs，然後實作API版本控制策略。當您準備好透過 REST、GraphQL 或非同步事件等常見通訊協定整合 服務時，您可以將 AWS 服務整合到您的架構中，以將元件與強式API合約整合。

 **AWS 服務API對象的服務** 

 將 [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 服務和其他 Web 服務整合。API Gateway 支援 [OpenAPI 規格](https://github.com/OAI/OpenAPI-Specification)和 versioning。 AWS AppSync 是您透過定義 [GraphQL](https://graphql.org/) 結構描述來定義查詢、突變和訂閱的服務界面所設定的受管 GraphQL 端點。Amazon EventBridge 使用事件結構描述來定義事件，並為您的事件產生程式碼繫結。

## 實作步驟
<a name="implementation-steps"></a>
+  首先，為您的 定義合約API。合約會表達 的功能API，並定義API輸入和輸出的強烈輸入資料物件和欄位。
+  當您APIs在 API Gateway 中設定 時，您可以匯入和匯出端點的開放API規格。
  +  [匯入 OpenAPI 定義](https://docs.aws.amazon.com/apigateway/latest/developerguide/import-edge-optimized-api.html)可簡化 的建立，API並可整合 AWS 基礎設施作為程式碼工具，例如 [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/)和 [AWS Cloud Development Kit (AWS CDK)](https://aws.amazon.com/cdk/)。
  +  [匯出API定義](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html)可簡化與API測試工具的整合，並為服務消費者提供整合規格。
+  您可以使用 APIs AWS AppSync 定義 GraphQL [結構描述檔案來定義和管理 GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)，以產生合約界面，並簡化與複雜REST模型、多個資料庫資料表或舊版服務的互動。
+  [AWS Amplify](https://aws.amazon.com/amplify/) 與 整合的專案 AWS AppSync 會產生強式 JavaScript 查詢檔案，用於您的應用程式，以及 [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) 資料表的 AWS AppSync GraphQL 用戶端程式庫。
+  當您從 Amazon 取用服務事件時 EventBridge，事件會遵守已存在於結構描述登錄檔中的結構描述，或是您使用 OpenAPI Spec 定義的結構描述。使用登錄中定義的結構描述時，您也可以從結構描述合約產生用戶端繫結，以將程式碼與事件整合。
+  擴展或版本您的 API。新增可使用選用欄位或必要欄位的預設值設定的欄位時，延伸 API 是更簡單的選項。
  +  JSON REST和 GraphQL 等通訊協定的 型合約非常適合合約延伸。
  +  XML 等通訊協定的 型合約SOAP應與 服務消費者進行測試，以判斷合約延伸的可行性。
+  版本控制 時API，請考慮實作 Proxy 版本控制，其中使用外觀來支援版本，以便在單一程式碼庫中維護邏輯。
  +  使用 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/)
+ [ 在 上實作 Microservices AWS](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/microservices-on-aws.html)
+ [微型服務權衡](https://martinfowler.com/articles/microservice-trade-offs.html)
+ [微型服務 - 此新架構術語的定義](https://www.martinfowler.com/articles/microservices.html)
+ [ 上的微服務 AWS](https://aws.amazon.com/microservices/)
+ [ 使用 API Gateway 擴充功能開啟API ](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions.html)
+ [ 開啟 API-規格 ](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：設定RESTAPI使用開啟API ](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html)
+ [ 使用 Open 的 Amazon API Gateway 至 Amazon DynamoDB CRUD 應用程式API ](https://serverlessland.com/patterns/apigw-ddb-openapi-crud?ref=search)
+ [ 無伺服器時代的現代應用程式整合模式：APIGateway Service Integration ](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 實作標頭型API閘道版本控制 CloudFront ](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)

 **相關影片：**
+ [ 使用在 中開啟API AWS SAM 管理API閘道 ](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>

 分散式系統可以是同步、非同步或批次處理。同步系統必須盡快處理要求，並透過使用 HTTP/S、REST 或遠端程序呼叫 (RPC) 通訊協定進行同步請求和回應呼叫，以便相互通訊。非同步系統透過中間服務以非同步方式交換資料來相互通訊，而不需要耦合個別系統。批處理系統接收大量輸入資料，無須人工介入即可執行自動化資料處理，並產生輸出資料。

 **預期成果**：設計與同步、非同步和批次相依性有效互動的工作負載。

 **常見的反模式：**
+  工作負載會無限期地等待來自其相依性的回應，這可能會導致工作負載用戶端逾時，而不知道是否已收到其請求。
+  工作負載使用可同步呼叫彼此的一系列相依系統。這需要每個系統都可供使用，並在整個系列成功之前成功處理請求，從而導致潛在的脆弱行為和整體可用性。
+  工作負載會以非同步方式與其相依性進行通訊，並依賴於僅保證傳遞訊息一次的概念，而且通常仍然可以接收重複的訊息。
+  工作負載不使用適當的批次排程工具，並允許同時執行相同的批次工作。

 **建立此最佳實務的優勢**：對於特定的工作負載來說，在同步、非同步和批次之間實作一種或多種通訊方式很常見。此最佳實務可協助您識別與每種通訊方式相關的不同權衡，讓您的工作負載能夠容忍其任何相依性中斷。

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

## 實作指引
<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)，以協助您在相依性遇到問題時對問題進行疑難排解。

 **同步相依性** 

 在同步通訊中，工作負載會將請求傳送至其相依性，並封鎖等待回應的操作。當其相依性收到請求時，它會嘗試盡快處理它，並將回應傳送回您的工作負載。同步通訊的一個重大挑戰是它會導致時間耦合，這需要您的工作負載及其相依性同時可用。當您的工作負載需要與其相依性同步通訊時，請考慮下列指引：
+  您的工作負載不應該依賴多個同步相依性來執行單一函數。此相依性系列增加了整體的脆弱性，因為路徑中的所有相依性都必須可用，才能順利完成請求。
+  當相依性狀態不良或無法使用時，請確定處理錯誤並重試策略。避免使用雙模態行為。雙模態行為是指工作負載在正常和故障模式下呈現不同行為的情況。如需雙模態行為的詳細資訊，請參閱 [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 函數時處理重試和失敗。
+  當工作負載呼叫其相依性時設定逾時。此技術可避免等待太長時間或無限期等待回應。如需此問題的有用討論，請參閱 [Tuning AWS Java SDK HTTP request settings for latency-aware Amazon DynamoDB applications](https://aws.amazon.com/blogs/database/tuning-aws-java-sdk-http-request-settings-for-latency-aware-amazon-dynamodb-applications/)。
+  盡可能減少從工作負載到其相依性的呼叫次數，以滿足單一請求。在兩者之間進行聊天呼叫會增加耦合和延遲。

 **異步相依性** 

 若要暫時將工作負載與其相依性分離，它們應該以非同步方式進行通訊。使用非同步方法，您的工作負載可以繼續執行任何其他處理，而不必等待其相依性或相依性系列來傳送回應。

 當您的工作負載需要與其相依性異步通訊時，請考慮下列指引：
+  根據您的使用案例和需求來決定是使用訊息傳遞還是事件串流。[訊息傳遞](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)。

 **批處理相依性** 

 批處理系統會取得輸入資料，啟動一系列作業來處理它，並產生一些輸出資料，無須人工介入。視資料大小而定，工作可能會執行幾分鐘，在某些情況下執行數天。當您的工作負載需要與其批處理相依性通訊時，請考慮下列指引：
+  定義工作負載執行批次工作的時間範圍。工作負載可以設定週期性模式來調用批次系統，例如，每小時或每月結束時。
+  確定資料輸入和已處理的資料輸出的位置。選擇可讓您的工作負載大規模讀取和寫入檔案的儲存服務，例如 [Amazon Simple Storage Services (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 雲端 操作：監控和可觀測性](https://aws.amazon.com/cloudops/monitoring-and-observability) 
+  [Amazon 建置者資料中心：分散式系統的挑戰](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 服務](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 函數，複雜的協調器應用程式](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 Services (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>

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

 解除相依性 (例如佇列系統、串流系統和工作流程) 有助於將變更或失敗對系統造成的影響降到最低。這種分離使組件的行為不會影響依賴它的其他組件，從而提高了彈性和敏捷性。

 在緊耦合的系統中，對某個元件進行變更時，可能必須變更其他依賴此元件的元件，從而導致所有元件的效能降低。*鬆*耦合會破壞此相依性，因此相依元件只需要知道受版本控制的和已發布的界面。在相依性之間實作鬆耦合，可避免一個元件中的故障影響另一個元件。

 鬆耦合可讓您修改程式碼或新增功能至某個元件，同時將依賴該元件的其他元件的風險降至最低。其還能讓您在元件層級提供細微的恢復能力，您可以橫向擴充，甚至是變更相依性的基礎實作。

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

![\[圖表顯示佇列系統和負載平衡器之間具有鬆散耦合的相依性\]](http://docs.aws.amazon.com/zh_tw/wellarchitected/latest/reliability-pillar/images/dependency-diagram.png)


 Amazon SQS佇列和 AWS Step Functions 只是新增中繼層以進行鬆散耦合的兩種方式。事件驅動的架構也可以 AWS 雲端 使用 Amazon 建置在 中 EventBridge，這可以從用戶端 （事件生產者） 仰賴的服務 （事件消費者） 中抽象用戶端 （事件生產者）。當您需要高輸送量、推送型訊息時， many-to-manyAmazon Simple Notification Service （Amazon SNS） 是有效的解決方案。使用 Amazon SNS主題，您的發佈者系統可以將訊息散播到大量訂閱者端點以進行平行處理。

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

 **預期成果：**實作鬆耦合的相依性可將元件層級故障的影響降到最低，這有助於診斷和解決問題。它還能簡化開發週期，讓團隊在模組化層級實作變更，而不會影響依賴此元件之其他元件的效能。這種方法可讓您根據資源需求，以及對成本效益有所貢獻之元件的使用情況，在元件層級進行橫向擴充。

 **常見的反模式：**
+  部署整合型工作負載。
+  直接在工作負載層APIs之間調用，而沒有容錯移轉或非同步處理請求的能力。
+  使用共用資料的緊耦合。鬆耦合系統應避免透過共用資料庫或其他形式的緊耦合資料儲存共用資料，這可能會重新引入緊耦合並阻礙可擴展性。
+  忽略反壓。當元件無法以相同的速率處理傳入的資料時，工作負載應該要有能力減緩或停止傳入的資料。

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

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

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

 實作鬆耦合相依性。有各種解決方案可讓您建置鬆耦合的應用程式。其中包括實作完全受管佇列、自動化工作流程、對事件做出反應APIs等服務，這些服務可協助隔離元件與其他元件的行為，進而提高復原能力和靈活性。
+  **建置事件驅動架構：**[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/)可讓團隊建置由小型獨立元件組成的應用程式，這些元件透過定義明確的 進行通訊APIs。[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 Notification 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)
+  分散式傳訊系統有三個需要針對佇列型架構來實作的主要部分。其中包括分散式系統的元件、用於解耦的佇列 （在 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/)
+  充分利用的微型服務會增強可維護性並提高可擴展性，因為鬆耦合元件由獨立團隊管理。其還能夠在發生變更時隔離單一元件的行為。
  + [ 在 上實作 Microservices AWS](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/microservices-on-aws.html)
  + [開始建構吧！使用容器建構微型服務](https://aws.amazon.com/blogs/architecture/lets-architect-architecting-microservices-with-containers/)
+  AWS Step Functions 您可以透過 建置分散式應用程式、自動化程序、協調微服務等。將多個元件協同運作到自動化工作流程中可讓您解耦應用程式中的相依性。
  + [ 使用 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 建置者資料中心：分散式系統的挑戰](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon 建置者資料中心：可靠性、持續工作以及咖啡時刻](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) 
+ [結束您的整合型架構](https://pages.awscloud.com/break-up-your-monolith.html)
+ [ 使用 AWS Step Functions 和 Amazon 協調佇列型 Microservices 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 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 Deep Dive 和最佳實務 ](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 建置者資料中心：可靠性、持續工作以及咖啡時刻](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 建置者資料中心：分散式系統的挑戰](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon 建置者資料中心：可靠性、持續工作以及咖啡時刻](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **相關影片：**
+  [AWS 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>

 冪等服務確保每個請求只處理一次，因此發出多個相同請求的效果，與發出單一請求的效果相同。如此一來，用戶端可更輕鬆地重試，而不用擔心多次錯誤地處理請求。為此，用戶端可以使用冪等性字符發出 API 請求，每次重複請求時，都會使用這個權杖。冪等服務 API 會使用字符傳回回應，而該回應與第一次完成請求時傳回的回應相同，即使系統的基礎狀態已改變也一樣。

 在分散式系統中，相對容易的做法是最多執行一次動作 (用戶端只發出一個請求) 或至少執行一次動作 (持續發出請求，直到用戶端確認成功)。但很難保證動作*精準地執行一次*，使得發出多個相同的請求與發出單一請求效果相同。透過在 API 中使用冪等性字符，服務可以收到一次或多次變異請求，而不需建立重複的記錄或產生副作用。

 **預期成果：**您擁有一致、完整記錄且廣泛採用的方法，以確保所有元件和服務之間的冪等性。

 **常見的反模式：**
+  即使不需要，您仍一視同仁地套用冪等性。
+  您導入過於複雜的邏輯來實作冪等性。
+  您使用時間戳記做為冪等性的索引鍵。這樣可能會因為時鐘誤差或多個用戶端使用相同的時間戳記來套用變更，而造成不準確。
+  您為了冪等性而儲存整個承載。採用這個方法時，您會為每個請求儲存完整的資料承載，並在每個新請求中覆寫它。這可能會導致效能降低並影響可擴展性。
+  您在服務之間產生不一致的索引鍵。若索引鍵不一致，服務可能無法辨識重複的請求，進而導致意外的結果。

 **建立此最佳實務的優勢：**
+  可擴展性更大：系統可以處理重試和重複的請求，而不需執行額外的邏輯或複雜的狀態管理。
+  加強可靠性：冪等性可協助服務以一致的方式處理多個相同的請求，進而降低意外副作用或重複記錄的風險。這在經常發生網路故障和重試的分散式系統中尤其重要。
+  改善資料一致性：由於相同的請求會產生相同的回應，因此冪等性有助於在分散式系統之間保持資料一致性。這對於維護交易和操作的完整性相當重要。
+  錯誤處理：冪等性字符讓錯誤處理更簡單。如果用戶端因發生問題而未收到回應，它可以使用相同的冪等性字符安全地重新傳送請求。
+  操作透明度：冪等性可實現更有效的監控與記錄。服務可以透過冪等性字符來記錄請求，這樣更容易追蹤問題並進行偵錯。
+  簡化的 API 合約：它可以簡化用戶端和伺服器端系統之間的合約，並減少對資料處理錯誤的擔憂。

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

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

 在分散式系統中，最多執行一次動作 (用戶端只發出一個請求) 或至少執行一次動作 (用戶端持續發出請求直到確認成功) 是相對容易的做法。不過，實作*精確一次*的行為並不容易。若要達成此目的，您的用戶端應針對每個請求產生並提供冪等性字符。

 透過使用冪等性字符，服務就能區分新請求和重複的請求。當服務收到具有冪等性字符的請求時，它會檢查字符是否已使用。如果已使用字符，服務就會擷取並傳回預存回應。如果字符是新的，則服務會處理請求、一併儲存回應與字符，然後傳回回應。此機制會讓所有回應變成冪等，進而提高分散式系統的可靠性和一致性。

 冪等性也是事件驅動架構的重要行為。這些架構通常由訊息佇列支援，例如 Amazon SQS、Amazon MQ、Amazon Kinesis Streams 或 Amazon Managed Streaming for Apache Kafka (MSK)。在某些情況下，只發布一次的訊息可能會意外傳遞超過一次。當發布者在訊息中產生並包含冪等性字符時，它會要求處理收到的任何重複訊息時，不會對相同訊息產生重複的動作。取用者應追蹤收到的每個字符，並忽略包含重複字符的訊息。

 服務與取用者也應將收到的冪等性字符傳遞給其呼叫的任何下游服務。處理鏈中的每個下游服務都同樣負責確保實作冪等性，以免發生處理訊息超過一次的副作用。

### 實作步驟
<a name="implementation-steps"></a>

1.  **識別冪等操作** 

    確定哪些操作需要冪等性。這些通常包括 POST、PUT 和 DELETE HTTP 方法，以及資料庫插入、更新或刪除操作。不會改變狀態的操作 (例如唯讀查詢) 通常不需要冪等性，除非有副作用。

1.  **使用唯一識別碼** 

    在傳送者傳送的每個冪等操作請求中包含唯一的字符，無論是直接在請求中，還是做為其中繼資料的一部分 (例如 HTTP 標頭)。這可讓接收者辨識和處理重複的請求或操作。常用於字符的識別碼包括[通用唯一識別碼 (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 可以儲存高輸送量、低延遲且成本低廉的冪等性字符。如果您的應用程式在插入時設定了 TTL 值，則 ElastiCache (Redis) 和 ElastiCache (Memcached) 也會自動讓冪等性字符過期。
   +  **Amazon Relational Database Service (RDS)**：您可以使用 Amazon RDS 來存放冪等性字符和相關的狀態資訊，特別是您的應用程式已將關聯式資料庫用於其他用途時。
   +  **Amazon Simple Storage Service (S3)**：Amazon S3 是高度可擴展且耐用的物件儲存服務，可用於存放冪等性字符和相關的中繼資料。S3 的版本控制功能在維護冪等操作的狀態方面特別實用。選擇儲存服務時，通常取決於以下因素：與冪等性相關的資料量、所需的效能特性、所須耐用性和可用性，以及冪等性機制與整體工作負載架構整合的方式。

1.  **實作冪等操作** 

    將您的 API 和工作負載元件設計為冪等。將冪等性檢查納入工作負載元件中。在您處理請求或執行操作之前，請先檢查唯一識別碼是否已處理。若已處理，則傳回先前的結果，而非再次執行操作。例如，若用戶端傳送建立使用者的請求，則檢查具有相同唯一識別碼的使用者是否已存在。如果使用者已存在，則應傳回現有的使用者資訊，而非建立新使用者。同樣地，如果佇列取用者收到的訊息中包含重複地冪等性字符，則取用者應忽略訊息。

    建立全方位的測試套件，以確認請求的冪等性。這些套件應涵蓋各種不同的案例，例如成功請求、失敗請求和重複請求。

    如果您的工作負載利用 AWS Lambda 函數，請考慮 Powertools for AWS Lambda。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) 

 **相關文件：**
+  [Amazon 建置者資料中心：透過冪等 API 安全地進行重試](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/) 
+  [Amazon 建置者資料中心：分散式系統的挑戰](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon 建置者資料中心：可靠性、持續工作以及咖啡時刻](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [Amazon Elastic Container Service：確保冪等性](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/ECS_Idempotency.html) 
+  [如何讓 Lambda 函數冪等？](https://repost.aws/knowledge-center/lambda-function-idempotent) 
+  [確保 Amazon EC2 API 請求中的冪等性](https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-idempotency.html) 

 **相關影片：**
+  [使用事件驅動型架構建置分散式應用程式 - AWS 線上技術講座](https://www.youtube.com/watch?v=gA2-eqDVSng&t=1668s) 
+  [AWS re:Invent 2023 - 使用事件驅動型架構建置新一代應用程式](https://www.youtube.com/watch?v=KXR17uwLEC8) 
+  [AWS re:Invent 2023 - 鬆耦合系統的進階整合模式和權衡](https://www.youtube.com/watch?v=FGKGdUiZKto) 
+  [AWS re:Invent 2023 - 使用 Amazon EventBridge 的進階事件驅動型模式](https://www.youtube.com/watch?v=6X4lSPkn4ps) 
+  [AWS re:Invent 2018 - 閉門造車與開放思維：如何取得大小型系統的控制權 (ARC337) (包括鬆耦合、持續工作、靜態穩定性)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019：移至事件驅動型架構 (SVS308)](https://youtu.be/h46IquqjF3E) 

 **相關工具：**
+  [AWS Lambda Powertools 的冪等性 (Java)](https://docs.powertools.aws.dev/lambda/java/utilities/idempotency/) 
+  [AWS Lambda Powertools 的冪等性 (Python)](https://docs.powertools.aws.dev/lambda/python/latest/utilities/idempotency/) 
+  [AWS Lambda Powertools GitHub 頁面](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>

即使相依性變得不可用，應用程式元件仍應繼續執行其核心功能。它們有可能提供稍微陳舊的資料、備用資料，甚至未提供任何資料。這可確保整體系統運作在本地化失敗時只會受到最低限度的阻礙，同時提供核心商業價值。

 **預期成果：**當元件的相依性狀況不良，元件本身仍可運作，但以降級的方式運作。元件的失敗模式應被視為正常運作。工作流程應適當設計，使此類失敗不會導致完全失敗，或至少會進入可預測和可復原的狀態。

 **常見的反模式：**
+  未識別所需的核心業務功能。即使在相依性失敗期間，也不測試元件是否正常運作。
+  發生錯誤時，或只有多個相依性的其中之一無法使用，且仍可傳回部分結果時，就不提供資料。
+  當交易部分失敗時建立不一致的狀態。
+  沒有替代方法可存取中央參數存放區。
+  因重新整理失敗而使本機狀態失效或清空，而未考量這麼做的後果。

 **建立此最佳實務的優勢：**按正常程序降級可改善系統整體的可用性，並且讓最重要的功能保持運作，即使在失敗期間亦然。

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

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

 按正常程序實作降級，有助於將相依性失敗對元件功能的影響降到最低。理想情況下，元件會偵測相依性失敗，並以對其他元件或客戶造成最小影響的方式解決這些問題。

 按正常程序降級的架構，意味著在相依性設計期間會考量潛在的失敗模式。對於每種失敗模式，都有一種方法可至少將元件最關鍵的功能提供給呼叫者或客戶。這些考量可能會成為可供測試和驗證的其他要求。理想情況下，即使有一或多個相依性失敗，元件仍然能夠以可接受的方式執行其核心功能。

 這在商業上和技術上都同樣值得討論。所有業務要求都很重要，都應盡可能地滿足。然而，若無法滿足各項要求將會如何，仍是值得提出的問題。一個系統可以設計成可用且一致的，但在必須放棄一項要求的情況下，何者較重要？ 對於付款處理，可能應選擇一致性。對於即時應用程式，可能應選擇可用性。對於面向客戶的網站，答案可能取決於客戶的期望。

 這意味著什麼，取決於元件的要求，以及應將哪些內容視為其核心功能。例如：
+  電子商務網站可能會顯示來自多個不同系統的資料，例如個人化推薦、排名最高的產品，以及客戶訂單在登陸網頁上的狀態。當一個上游系統失敗時，顯示其他所有內容，而不是向客戶顯示錯誤頁面，仍然是合理的。
+  如果個別作業之一失敗，執行批次寫入的元件仍然可以繼續處理批次。實作重試機制應該要很簡單。為此，您可以向呼叫者傳回關於哪些操作成功、哪些操作失敗及其為何失敗的資訊，或將失敗的請求放入無效字母佇列以實作非同步重試。失敗操作的相關資訊也應記錄下來。
+  處理交易的系統必須確認是否執行了所有更新，或完全未執行更新。對於分佈式交易，可使用 Saga 模式在相同交易的後續操作失敗的情況下回復先前的操作。在此，核心功能保有一致性。
+  具時間性的系統應該能夠處理未及時回應的相依性。在這類情況下，可以使用斷路器模式。若來自相依性的回應開始逾時，系統可以切換到不會進行其他呼叫的關閉狀態。
+  應用程式可從參數存放區讀取參數。使用一組預設的參數建立容器映像，並在參數存放區無法使用時使用這些參數，會很有效用。

 請注意，在元件失敗的情況下採取的路徑需進行測試，且應遠比主要途徑簡單。一般來說，[應避免使用備用策略](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems/)。

## 實作步驟
<a name="implementation-steps"></a>

 識別外部和內部相依性。請考量其中可能會發生什麼樣的失敗。思考在這類失敗期間，將上游和下游系統以及客戶受到的負面影響降到最低的方法。

 以下列出相依性，並說明如何在其失敗時按正常程序降級：

1.  **相依性的部分失敗：**一個元件可能會向下游系統提出多個請求，可以是對一個系統的多個請求，或者對多個系統各提出一個請求。視業務環境而定，對此可能會有不同的適當處理方式 (如需詳細資訊，請參閱實作指引中的先前範例)。

1.  **下游系統因高負載而無法處理請求：**如果對下游系統的請求一直失敗，則繼續重試是沒有意義的。這樣可能會對已過載的系統產生額外的負載，並使復原變得更加困難。此時可以使用斷路器模式，以監控對下游系統的失敗呼叫。若有大量呼叫失敗，將會停止向下游系統傳送更多請求，且偶爾才會讓呼叫通過，以測試下游系統是否已恢復可用性。

1.  **參數存放區無法使用：**若要轉換參數存放區，可以使用容器或機器映像中包含的軟相依性快取或有效的預設值。請注意，這些預設值需要保持最新狀態，並包含在測試套件中。

1.  **監控服務或其他非功能性相依性無法使用：**如果元件間歇性地無法傳送記錄、指標或追蹤給中央監控服務，最好還是照常執行業務功能。一般而言，長時間不日誌記錄或推送指標且未顯示任何訊息，是不可接受的。此外，某些使用案例可能需要完整的稽核項目才能滿足合規要求。

1.  **關聯式資料庫的主要執行個體可能無法使用：**Amazon Relational Database Service 與幾乎所有關聯式資料庫一樣，只能有一個主要寫入器執行個體。這會對寫入工作負載造成單一失敗點，並使擴展變得更加困難。透過使用多可用區域組態以獲得高可用性，或使用 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) 
+  [CircuitBreaker (摘要說明「Release It\$1」書籍中的斷路器)](https://martinfowler.com/bliki/CircuitBreaker.html) 
+  [AWS 中的錯誤重試與指數退避](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [Michael Nygard “Release It\$1 Design and Deploy Production-Ready Software”](https://pragprog.com/titles/mnee2/release-it-second-edition/) 
+  [Amazon 建置者資料中心：避免分散式系統的備用](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [Amazon 建置者資料中心：避免無法逾越的佇列待辦項目](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs) 
+  [Amazon 建置者資料中心：快取挑戰和策略](https://aws.amazon.com/builders-library/caching-challenges-and-strategies/) 
+  [Amazon 建置者資料中心：逾時、重試、退避與抖動](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 

 **相關影片：**
+  [重試、退避和抖動：AWS re:Invent 2019：Amazon 建置者資料中心簡介 (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>

 服務應設計為處理已知的請求容量；此容量可透過負載測試來建立。如果請求到達率超過限制，會有適當的回應訊號指出請求已受到限流。這可讓取用者處理錯誤並於稍後重試。

 當您的服務需要限流實作時，請考慮實作權杖儲存貯體演算法 (在此演算法中，權杖對於請求具重要性)。權杖會按每秒的限流率重新填入，並依照每個請求一個權杖的比例非同步清空。

![\[說明權杖儲存貯體演算法的圖表。\]](http://docs.aws.amazon.com/zh_tw/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 的限流限制來設定 API Gateway，並在超出限制時傳回 `429 Too Many Requests` 錯誤。可以搭配使用 AWS WAF 與 AWS AppSync 和 API Gateway 端點，以按照 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)
+ [導入使用 Amazon SQS 作為事件來源時的 AWS Lambda 並行上限](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)

 **相關範例：**
+ [三項最重要的 AWS WAF 以速率為基礎的規則](https://aws.amazon.com/blogs/security/three-most-important-aws-waf-rate-based-rules/)
+ [Java Bucket4j](https://github.com/bucket4j/bucket4j)
+ [Python 權杖儲存貯體](https://pypi.org/project/token-bucket/)
+ [節點權杖儲存貯體](https://www.npmjs.com/package/tokenbucket)
+ [.NET 系統執行緒速率限制](https://www.nuget.org/packages/System.Threading.RateLimiting)

 **相關影片：**
+ [使用 AWS AppSync 實作 GraphQL API 安全最佳實務](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 SQS](https://aws.amazon.com/sqs/)
+ [Amazon Kinesis](https://aws.amazon.com/kinesis/)
+ [AWS WAF](https://aws.amazon.com/waf/)
+ [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而不測試重試案例。
+  未能了解從相依性發布的錯誤代碼，因而重試了所有錯誤，包括有明確原因指出缺少權限的錯誤、組態錯誤，或其他預期必須要手動干預才能解決的狀況。
+  未解決可觀測性實務，包括對重複的服務失敗進行監控和提醒，使基礎問題廣為人知並且可以解決。
+  在內建或第三方重試功能堪用時，開發自訂重試機制。
+  以複合重試的方式在應用程式堆疊的多個層級重試，會嘗試在重試風暴中進一步耗用資源。請務必了解這些錯誤如何影響您所依賴的應用程式，然後僅在一個層級實作重試。
+  重試不是等冪的服務呼叫，導致非預期的副作用，例如重複的結果。

 **建立此最佳實務的優勢：**重試可協助用戶端在請求失敗時獲得所需的結果，但也會耗用更多伺服器的時間來取得他們想要的成功回應。若失敗是罕見或暫時性的，重試可以有效運作。若失敗是由資源超載引起的，重試可能會使情況變得更糟。在用戶端重試中新增具有抖動的指數退避，可讓伺服器在資源超載導致失敗時進行復原。抖動可避免將請求對應到尖峰，而退避會減少將重試新增至正常請求負載所造成的負載上升。最後，請務必設定最大重試次數或經過時間，以避免建立會產生亞穩態失敗的積存。

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

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

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

 有些 AWS SDKs依預設會實作重試和指數退避。在工作負載中適用的情況下，使用這些內建 AWS 實作。在呼叫等冪的服務時，以及重試可改善用戶端可用性時，在您的工作負載中實作類似的邏輯。根據您的使用案例確定逾時時間以及何時停止重試。為那些重試使用案例建置和模擬演練測試情境。

## 實作步驟
<a name="implementation-steps"></a>
+  確認應用程式堆疊中的最佳層級，以針對您應用程式所依賴的服務實作重試。
+  請注意，現有的 SDKs 會針對您選擇的語言實作經過驗證的重試策略，並具有指數退避和抖動，並且比編寫您自己的重試實作更有利。
+  在實作重試之前，請確認[服務是冪等的](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/)。實作重試後，請務必在生產環境中加以測試和定期模擬演練。
+  呼叫 AWS 服務 時APIs，請使用 [AWS SDKs](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 建置者資料中心：逾時、重試、退避與抖動](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 
+ [指數退避和抖動](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/)
+ [ 以無能方式確保重試安全 APIs ](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/)

 **相關範例：**
+ [Spring 重試](https://github.com/spring-projects/spring-retry)
+ [Resilience4j 重試](https://resilience4j.readme.io/docs/retry)

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

 **相關工具：**
+ [AWS SDKs 和 工具：重試行為 ](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) 或警示，以偵測系統失敗。
+  未測量訊息在佇列中的存留期，這是一種延遲測量，用以了解佇列取用者何時進度落後或發生錯誤導致重試。
+  當處理這些訊息沒有任何價值，且業務需求已不存在時，未清除佇列中已積存的訊息。
+  在後進先出 (LIFO) 佇列可更妥善地滿足用戶端需求時設定了先進先出 (FIFO) 佇列，例如，當不需要嚴格排序，以及積存處理延遲了所有新的和時間敏感的請求，導致所有用戶端都經歷違反服務水準的狀況。
+  將內部佇列公開給用戶端，而不是公開管理工作接受以及將請求放入內部佇列的 API。
+  藉由將資源需求分攤到不同請求型態，將過多的工作請求類型合併到可能加劇積存條件的單一佇列中。
+  儘管需要不同的監控、逾時和資源分配，仍在同一佇列中處理複雜而簡單的請求。
+  不驗證輸入或使用判斷提示在軟體中實作快速檢錯的機制，以對可用正常程序處理錯誤的較高層級元件快顯例外狀況。
+  不會從請求路由中移除錯誤的資源，特別是在失敗處於灰色地帶，因損毀和重新啟動、間歇性相依性失敗、容量減少或網路封包遺失而導致成功與失敗並存。

 **建立此最佳實務的優勢：**快速檢錯的系統更容易偵錯和修正，並且在發佈至生產環境之前，常會出現編碼和組態方面的問題。納入有效佇列策略的系統，可針對流量尖峰和間歇性系統失敗狀況提供更高的恢復能力和可靠性。

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

## 實作指引
<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 指標和警示背離受損的資源，這些資源會增加處理的延遲，或持續無法處理請求。
+  藉由設計 API 使用非同步處理來接受請求，並使用 Amazon SQS 將請求附加到內部佇列，然後透過成功訊息回應產生訊息的用戶端，讓用戶端可以釋出資源並繼續進行其他工作，同時讓後端佇列取用者處理請求。
+  藉由比較現在時間與訊息時間戳記，在每次從佇列中取出訊息時產生 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/)
+  [快速檢錯](https://www.martinfowler.com/ieeeSoftware/failFast.pdf) 
+ [如何防止 Amazon SQS 佇列中不斷增加的積存訊息？](https://repost.aws/knowledge-center/sqs-message-backlog)
+ [Elastic Load Balancing：區域轉移](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/zonal-shift.html)
+ [Amazon 應用程式復原控制器：流量容錯移轉的路由控制](https://docs.aws.amazon.com/r53recovery/latest/dg/getting-started-routing-controls.html)

 **相關範例：**
+ [企業整合模式：無效字母通道](https://www.enterpriseintegrationpatterns.com/patterns/messaging/DeadLetterChannel.html)

 **相關影片：**
+  [AWS re:Invent 2022 - 操作高可用性多可用區域應用程式](https://www.youtube.com/watch?v=mwUV5skJJ0s) 

 **相關工具：**
+ [ Amazon SQS](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>

 針對任何服務相依性呼叫和任何跨程序的呼叫，同時設定連線逾時和請求逾時。許多架構都提供內建的逾時功能，但請注意，對您的服務目標而言，有些架構具有無限或過高的預設值。太高的值會降低逾時的實用性，因為當用戶端等待逾時發生時，資源會持續耗用。太低的值可能會增加後端流量和延遲，原因是重試的請求過多。在某些情況下，這可能導致完全停機，原因是正在重試所有請求。

 決定逾時策略時，請考量下列事項：
+  由於請求的內容、目標服務受損或聯網分割失敗，處理請求的時間可能會比平常更長。
+  內容異常昂貴的請求可能會耗用不必要的伺服器和用戶端資源。在此情況下，讓這些請求逾時而不重試，可以保留資源。服務也應透過限流和伺服器端逾時，來保護自己免受異常昂貴的內容影響。
+  因服務受損而異常耗時的請求可能會逾時並重試。應考量請求和重試的服務成本，但如果原因是當地語系化的損害，則重試應該不會很昂貴，而且將可降低用戶端資源耗用量。逾時也可能會根據損害的性質釋出伺服器資源。
+  因網路傳遞請求或回應失敗而需要長時間才能完成的請求，可能會逾時並重試。由於請求或回應未傳遞，因此無論逾時長度為何，結果都是失敗。在此情況下，逾時不會釋出伺服器資源，但會釋出用戶端資源並改善工作負載效能。

 利用如重試和斷路器等建立良好的設計模式，優雅地處理逾時，並支援快速失敗的方法。[AWS SDKs](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 和 預先建置的整合SDKs。 [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 CLI 命令時 AWS SDKs，請設定 `connectTimeoutInMillis`和 的 AWS [組態預設值](https://docs.aws.amazon.com/sdkref/latest/guide/feature-smart-config-defaults.html)，以設定預設逾時值`tlsNegotiationTimeoutInMillis`。
+  將[命令列選項](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html) `cli-connect-timeout`和 套用至 AWS 服務`cli-read-timeout`，以控制一次性 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 原生SDKs和支援的 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 建置者資料中心：逾時、重試、退避與抖動](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 
+ [ Amazon API Gateway 配額和重要備註 ](https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html)
+ [AWS Command Line Interface：命令列選項](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html)
+ [AWS SDK for Java 2.x：設定API逾時 ](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/best-practices.html#bestpractice5)
+ [AWS 使用組態物件和組態參考的 Botocore ](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#using-the-config-object)
+ [適用於 .NET 的 AWS SDK：重試與逾時](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html)
+ [AWS Lambda：設定 Lambda 函數選項](https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html)

 **相關範例：**
+ [ 搭配 AWS Step Functions 和 Amazon DynamoDB 使用斷路器模式 ](https://aws.amazon.com/blogs/compute/using-the-circuit-breaker-pattern-with-aws-step-functions-and-amazon-dynamodb/)
+ [ Martin Fowler： CircuitBreaker ](https://martinfowler.com/bliki/CircuitBreaker.html?ref=wellarchitected)

 **相關工具：**
+ [AWS SDKs ](https://docs.aws.amazon.com/index.html#sdks)
+ [AWS Lambda](https://aws.amazon.com/lambda/)
+ [ Amazon SQS ](https://aws.amazon.com/sqs/)
+ [AWS Step Functions](https://aws.amazon.com/step-functions/)
+ [AWS Command Line Interface](https://aws.amazon.com/cli/)

# REL05-BP06 盡可能讓系統處於無狀態
<a name="rel_mitigate_interaction_failure_stateless"></a>

 系統不應要求狀態，或應該卸載狀態，以便在不同的用戶端請求之間，不依賴磁碟和記憶體中本機儲存的資料。這允許伺服器任意置換，而不會對可用性造成影響。

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

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

 除了伺服器替換之外，無狀態應用程式的另一個優點是他們可以水平擴展，因為任何可用的運算資源 （例如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/) 來存放使用者設定檔等資訊。應用程式可以近乎即時的速度查詢這些資料。
+  將工作階段資料卸載至資料庫、快取或外部檔案。
  +  [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/) 是可用來卸載工作階段資料 AWS 的服務範例。
+  在確定需要使用所選儲存解決方案維持哪些狀態和使用者資料之後，設計一個無狀態架構。

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

 **相關的最佳實務：**
+  [REL11-BP03 在所有圖層上自動復原](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_withstand_component_failures_auto_healing_system.html) 

 **相關文件：**
+  [Amazon 建置者資料中心：避免分散式系統的備用](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [Amazon 建置者資料中心：避免無法逾越的佇列待辦項目](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs) 
+  [Amazon 建置者資料中心：快取挑戰和策略](https://aws.amazon.com/builders-library/caching-challenges-and-strategies/) 
+  [上的無狀態 Web 層最佳實務 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 搜尋功能如何使用混沌工程每秒處理 84K 以上的請求](https://community.aws/posts/how-search-uses-chaos-engineering) 

 **相關影片：**
+ [AWS re：Invent 2020：透過不可變性的可靠性、一致性和信心](https://www.youtube.com/watch?v=jUSYnRztttY)