

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon SQS 訊息重複資料刪除和分組
<a name="best-practices-message-deduplication"></a>

本主題提供最佳實務，以確保 Amazon SQS 中的訊息處理一致。它說明如何使用：
+ [https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html#API_SendMessage_RequestSyntax](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html#API_SendMessage_RequestSyntax) 以防止 FIFO 佇列中的重複訊息。
+ [https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html) 在不同的訊息群組中管理訊息排序。

****主題****
+ [避免在 Amazon SQS 中處理不一致的訊息](avoiding-inconsistent-message-processing.md)
+ [使用訊息重複資料刪除 ID](using-messagededuplicationid-property.md)
+ [使用訊息群組 ID](using-messagegroupid-property.md)
+ [使用接收請求嘗試 ID](using-receiverequestattemptid-request-parameter.md)

# 避免在 Amazon SQS 中處理不一致的訊息
<a name="avoiding-inconsistent-message-processing"></a>

因為 Amazon SQS 是分散式系統，所以即使 Amazon SQS 在 [https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) API 方法呼叫成功傳回時將訊息標示為已交付，消費者還是可能不會收到訊息。在此情況下，儘管消費者從未收到訊息，Amazon SQS 仍會將訊息記錄為交付至少一次。因為在這些情況下沒有其他嘗試交付訊息的動作，所以我們不建議將[無效字母佇列](sqs-dead-letter-queues.md)的接收數目上限設定為 1。

# 在 Amazon SQS 中使用訊息重複資料刪除 ID
<a name="using-messagededuplicationid-property"></a>

[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html) 是一種字符，僅用於 Amazon SQS FIFO 佇列，以防止重複的訊息傳遞。它可確保在 5 分鐘的重複資料刪除時段內，只會處理和交付具有相同重複資料刪除 ID 的訊息執行個體。

如果 Amazon SQS 已接受具有特定重複資料刪除 ID 的訊息，則會確認具有相同 ID 的任何後續訊息，但不會交付給消費者。

**注意**  
即使訊息已接收和刪除，Amazon SQS 仍會繼續追蹤重複資料刪除 ID。

**Topics**
+ [在 Amazon SQS 中提供訊息重複資料刪除 ID 的時機](providing-message-deduplication-id.md)
+ [在 Amazon SQS 中啟用單一生產者/消費者系統的重複資料刪除](single-producer-single-consumer.md)
+ [Amazon SQS 中的中斷復原案例](designing-for-outage-recovery-scenarios.md)
+ [在 Amazon SQS 中設定可見性逾時](working-with-visibility-timeouts.md)

# 在 Amazon SQS 中提供訊息重複資料刪除 ID 的時機
<a name="providing-message-deduplication-id"></a>

在下列案例中，生產者應指定訊息重複資料刪除 ID：
+ 傳送必須視為唯一的相同訊息內文時。
+ 傳送具有相同內容但不同訊息屬性的訊息時，請確保個別處理每個訊息。
+ 傳送具有不同內容的訊息時 （例如，訊息內文中的重試計數器），但要求 Amazon SQS 將其識別為重複。

# 在 Amazon SQS 中啟用單一生產者/消費者系統的重複資料刪除
<a name="single-producer-single-consumer"></a>

如果您有單一生產者和單一取用者，且訊息是唯一的，因為它們在內文中包含應用程式特定的訊息 ID，請遵循下列最佳實務：
+ 為佇列啟用內容型重複資料刪除 (每個訊息都有唯一的內文)。生產者可省略訊息重複資料刪除 ID。
+ 為 Amazon SQS FIFO 佇列啟用內容型重複資料刪除功能，並使用重複資料刪除 ID 傳送訊息時，重複資料刪除 ID [https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html) 會覆寫產生的內容型重複資料刪除 ID。
+ 雖然消費者不需要為每個請求提供接收請求嘗試 ID，但最佳實務仍建議這麼做，因為這樣可讓失敗重試序列執行得更快。
+ 您可以重試傳送或接收請求，因為它們不會干擾 FIFO 佇列中的訊息順序。

# Amazon SQS 中的中斷復原案例
<a name="designing-for-outage-recovery-scenarios"></a>

FIFO 佇列中的重複資料刪除程序分秒必爭。設計應用程式時，請確保生產者和消費者都可以從用戶端或網路中斷中復原，而不會造成重複或處理失敗。

生產者考量事項
+ Amazon SQS 會強制執行 5 分鐘的重複資料刪除時段。
+ 如果生產者在 5 分鐘後重試[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)請求，Amazon SQS 會將其視為新訊息，可能會建立重複項目。

消費者考量事項
+ 如果消費者無法在可見性逾時到期之前處理訊息，另一個消費者可能會接收並處理訊息，導致重複處理。
+ 根據應用程式的處理時間調整可見性逾時。
+ 使用 [https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibility.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibility.html) API 在訊息仍在處理時延長逾時。
+ 如果訊息重複無法處理，請將其路由到[無效字母佇列 (DLQ)](sqs-dead-letter-queues.md)，而不是允許無限期地重新處理。
+ 生產者必須注意到佇列的重複資料刪除間隔。Amazon SQS 的最低重複資料刪除間隔為 5 分鐘。在重複資料刪除間隔過期之後重試 `SendMessage` 請求，可能會將重複的訊息引進佇列中。例如，在汽車中的行動裝置傳送訊息，其順序很重要。如果在收到確認前汽車失去行動連線一段時間，則在重新連上行動連線後重試請求便會建立重複的訊息。
+ 消費者必須擁有可見性逾時，以將可見性逾時過期前無法處理訊息的風險降至最低。訊息正在處理時，您可以呼叫 `ChangeMessageVisibility` 動作來延長可見性逾時。不過，如果可見性逾時已過期，另一個消費者可以立即開始處理訊息，如此會導致多次處理同一則訊息。若要避免這種情況，請設定[無效字母佇列](sqs-dead-letter-queues.md)。

# 在 Amazon SQS 中設定可見性逾時
<a name="working-with-visibility-timeouts"></a>

為了確保可靠的訊息處理，請將可見性逾時設定為比 AWS SDK 讀取逾時更長。這適用於搭配短輪詢和長輪詢使用 [https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) API 時。較長的可見性逾時可防止訊息在原始請求完成之前可供其他消費者使用，從而降低重複處理的風險。

# 搭配 Amazon SQS FIFO 佇列使用訊息群組 ID
<a name="using-messagegroupid-property"></a>

在 FIFO First-In-First-Out佇列中， [https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html) 是將訊息組織成不同群組的屬性。相同訊息群組內的訊息一律以嚴格順序一次處理一個訊息，確保不會同時處理來自相同群組的兩個訊息。在標準佇列中，使用 `MessageGroupId`可啟用[公平佇列](sqs-fair-queues.md)。如果需要嚴格排序，請使用 FIFO 佇列。

**Topics**
+ [在 Amazon SQS 中交錯多個排序的訊息群組](interleaving-multiple-ordered-message-groups.md)
+ [在 Amazon SQS 的多生產者/消費者系統中防止重複處理](avoding-processing-duplicates-in-multiple-producer-consumer-system.md)
+ [避免在 Amazon SQS 中使用相同訊息群組 ID 的大型訊息待處理項目](avoid-backlog-with-the-same-message-group-id.md)
+ [避免在 Amazon SQS 中將相同的訊息群組 ID 與虛擬佇列重複使用](avoiding-reusing-message-group-id-with-virtual-queues.md)

# 在 Amazon SQS 中交錯多個排序的訊息群組
<a name="interleaving-multiple-ordered-message-groups"></a>

若要在單一 FIFO 佇列中交錯多個排序訊息群組，[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)請將 指派給每個群組 （例如，不同使用者的工作階段資料）。這可讓多個取用者同時從佇列讀取，同時確保依順序處理相同群組中的訊息。

當具有特定 的訊息`MessageGroupId`正在處理且隱藏時，直到可見性逾時過期或刪除訊息之前，其他取用者都無法處理來自相同群組的訊息。

# 在 Amazon SQS 的多生產者/消費者系統中防止重複處理
<a name="avoding-processing-duplicates-in-multiple-producer-consumer-system"></a>

在訊息排序不是優先順序的高輸送量、低延遲系統中，生產者可以[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)為每個訊息指派唯一的 。這可確保 Amazon SQS FIFO 佇列即使在多生產者/多消費者設定中也能消除重複項目。雖然此方法可防止重複的訊息，但它不保證訊息排序，因為每個訊息都被視為自己的獨立群組。

在具有多個生產者和消費者的任何系統中，一律會有重複交付的風險。如果消費者無法在可見性逾時到期之前處理訊息，Amazon SQS 會再次提供訊息，可能允許其他消費者接收訊息。若要緩解這種情況，請根據處理時間確保適當的訊息確認和可見性逾時設定。

# 避免在 Amazon SQS 中使用相同訊息群組 ID 的大型訊息待處理項目
<a name="avoid-backlog-with-the-same-message-group-id"></a>

FIFO 佇列最多支援 120，000 個傳輸中訊息 （消費者收到但尚未刪除的訊息）。如果達到此限制，Amazon SQS 不會傳回錯誤，但處理可能會受到影響。您可以聯絡 [AWS Support](https://docs.aws.amazon.com/awssupport/latest/user/create-service-quota-increase.html) 請求提高超過此限制。

FIFO 佇列會掃描前 120，000 則訊息，以判斷可用的訊息群組。如果大型待處理項目累積在單一訊息群組中，稍後傳送的其他群組的訊息將保持封鎖狀態，直到處理待處理項目為止。

**注意**  
當消費者重複無法處理訊息時，可能會發生訊息待處理項目。這可能是因為訊息內容問題或消費者端故障。為避免訊息處理延遲，請設定[無效字母佇列](sqs-dead-letter-queues.md)，在多次失敗嘗試後移動未處理的訊息。這可確保可以處理相同訊息群組中的其他訊息，防止系統瓶頸。

# 避免在 Amazon SQS 中將相同的訊息群組 ID 與虛擬佇列重複使用
<a name="avoiding-reusing-message-group-id-with-virtual-queues"></a>

搭配共用主機佇列使用虛擬佇列時，請避免在不同虛擬佇列[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)之間重複使用相同的佇列。如果多個虛擬佇列共用相同的主機佇列，並包含具有相同 的訊息`MessageGroupId`，則這些訊息可以彼此封鎖，從而防止有效率的處理。為了確保訊息處理順暢，請為不同虛擬佇列中的訊息指派唯一`MessageGroupId`值。

# 使用 Amazon SQS 接收請求嘗試 ID
<a name="using-receiverequestattemptid-request-parameter"></a>

接收請求嘗試 ID 是用來刪除 Amazon SQS 中重複[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html)呼叫的唯一權杖。在應用程式與 Amazon SQS 之間的網路中斷或連線問題期間，最佳實務是：
+ `ReceiveMessage` 呼叫時提供接收請求嘗試 ID。
+ 如果操作失敗，請使用相同的接收請求嘗試 ID 重試。