

# 在分散式系統中設計防止失敗的互動
<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/) 