

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

# Amazon SNS 無效字母佇列
<a name="sns-dead-letter-queues"></a>

無效字母佇列是一種 Amazon SQS 佇列，Amazon SNS 將它作為無法成功傳遞給訂閱者訊息的目標。由於用戶端錯誤或伺服器錯誤而無法傳遞的訊息，會保留在無效字母佇列，以供進一步分析或重新處理。如需詳細資訊，請參閱[設定訂閱的 Amazon SNS 無效字母佇列](sns-configure-dead-letter-queue.md)及[Amazon SNS 訊息傳遞重試](sns-message-delivery-retries.md)。

**注意**  
Amazon SNS 訂閱和 Amazon SQS 佇列必須位於相同的 AWS 帳戶和區域下。
對於 [FIFO 主題](sns-fifo-topics.md)，您可以使用 Amazon SQS 佇列做為 Amazon SNS 訂閱的無效字母佇列。FIFO 主題訂閱使用 FIFO 佇列，而標準主題訂閱則使用標準佇列。
若要使用加密的 Amazon SQS 佇列做為無效字母佇列，您必須使用具有金鑰政策的自訂 KMS，以授予 Amazon SNS 服務主體對 AWS KMS API 動作的存取權。如需詳細資訊，請參閱本指南中的 [使用伺服器端加密保護 Amazon SNS 資料](sns-server-side-encryption.md) 及 *Amazon Simple Queue Service 開發人員指南*中的[保護 Amazon SQS 資料與使用伺服器端加密 (SSE) 和 AWS KMS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-server-side-encryption.html)。

## 訊息傳遞為何失敗？
<a name="why-do-message-deliveries-fail"></a>

一般而言，當 Amazon SNS 因*用戶端*或*伺服器端錯誤*而無法存取訂閱的端點時，訊息傳遞就會失敗。當 Amazon SNS 收到用戶端錯誤，或繼續收到伺服器端錯誤 (因為訊息超出對應重試政策所指定的重試次數)，除非已將無效字母佇列附加至訂閱，否則 Amazon SNS 就會捨棄訊息。失敗傳遞不會改變您的訂閱狀態。如需詳細資訊，請參閱[Amazon SNS 訊息傳遞重試](sns-message-delivery-retries.md)。

### 用戶端錯誤
<a name="client-side-errors"></a>

當 Amazon SNS 有過時的訂閱中繼資料時，可能就會發生用戶端錯誤。當擁有者刪除端點 (例如對 Amazon SNS 主題訂閱的 Lambda 函數) 或擁有者變更附加至訂閱端點的政策而阻止 Amazon SNS 將訊息傳遞至端點，則經常會發生這些錯誤。Amazon SNS 不會重試因用戶端錯誤而失敗的訊息傳遞。

### 伺服器端錯誤
<a name="server-side-errors"></a>

當負責訂閱端點的系統無法使用或傳回例外狀況，表示無法處理 Amazon SNS 的有效請求，可能就會發生伺服器端錯誤。發生伺服器端錯誤時，Amazon SNS 會使用線性或指數退避函數來重試失敗的傳遞。對於由 Amazon SQS 或 支援的 AWS 受管端點引起的伺服器端錯誤 AWS Lambda，Amazon SNS 會在 23 天內重試交付最多 100，015 次。

客戶管理的端點 (例如 HTTP、SMTP、SMS 或行動推播) 可能也會導致伺服器端錯誤。Amazon SNS 也會重試傳遞到這些類型的端點。雖然 HTTP 端點支援客戶定義的重試政策，但針對 SMTP、SMS 和行動推播端點，Amazon SNS 會將內部傳遞重設政策設為 6 小時內 50 次。

## 無效字母佇列的運作方式
<a name="how-do-dead-letter-queues-work"></a>

無效字母佇列會附加至 Amazon SNS 訂閱 (而不是主題)，因為訊息傳遞是在訂閱層級發生。這可讓您更輕鬆地識別每個訊息的原始目標端點。

與 Amazon SNS 訂閱相關聯的無效字母佇列是一般的 Amazon SQS 佇列。如需訊息保留期間的詳細資訊，請參閱 *Amazon Simple Queue Service 開發人員指南*中的[訊息相關配額](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-quotas.html#quotas-messages)。您可以使用 Amazon SQS `[SetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html)` API 動作來變更訊息保留期間。若要讓應用程式更具彈性，建議您將無效字母佇列的最大保留期間設為 14 天。

## 訊息如何移至無效字母佇列？
<a name="how-messages-moved-into-dead-letter-queue"></a>

訊息是透過*再驅動政策*移至無效字母佇列。再驅動政策是參照無效字母佇列之 ARN 的 JSON 物件。`deadLetterTargetArn` 屬性會指定 ARN。ARN 必須指向與您的 Amazon SNS 訂閱位於相同 和 區域中的 Amazon SQS 佇列。 AWS 帳戶 Amazon SNS 如需詳細資訊，請參閱[設定訂閱的 Amazon SNS 無效字母佇列](sns-configure-dead-letter-queue.md)。

以下 JSON 物件是附加至 SNS 訂閱的再驅動政策範例。

```
{
  "deadLetterTargetArn": "arn:aws:sqs:us-east-2:123456789012:MyDeadLetterQueue"
}
```

## 如何將訊息從無效字母佇列中移出？
<a name="how-to-move-messages-out-of-dead-letter-queue"></a>

您可以透過下列兩種方式將訊息從無效字母佇列中移出：
+ **避免編寫 Amazon SQS 消費者邏輯** - 將無效字母佇列設為 Lambda 函數的事件來源，以耗盡無效字母佇列。
+ **寫入 Amazon SQS 取用者邏輯** – 使用 Amazon SQS API、 AWS SDK 或 AWS CLI 撰寫自訂取用者邏輯，以輪詢、處理和刪除無效字母佇列中的訊息。

## 如何監控和記錄無效字母佇列？
<a name="how-to-monitor-log-dead-letter-queues"></a>

您可以使用 Amazon CloudWatch 指標來監控與您 Amazon SNS 訂閱相關聯的無效字母佇列。所有 Amazon SQS 佇列都會每隔一分鐘發出 CloudWatch 指標。如需詳細資訊，請參閱《[Amazon Simple Queue Service 開發人員指南》中的適用於 Amazon SQS 的 CloudWatch 指標](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-available-cloudwatch-metrics.html)。 **所有包含無效字母佇列的 Amazon SNS 訂閱也會發出 CloudWatch 指標 如需詳細資訊，請參閱[使用 Amazon CloudWatch 監控 Amazon SNS 主題](sns-monitoring-using-cloudwatch.md)。

若要獲得無效字母佇列中的活動通知，您可以使用 CloudWatch 指標和警示。為`NumberOfMessagesSent`指標設定警示並不合適，因為此指標不會擷取因處理嘗試失敗而傳送到 DLQ 的訊息。反之，請使用 `ApproximateNumberOfMessagesVisible` 指標，該指標會擷取 DLQ 中目前可用的所有訊息，包括因處理失敗而移動的訊息。

**CloudWatch 警示設定範例**

1. 建立指標的 [CloudWatch 警示](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ConsoleAlarms.html)。 `ApproximateNumberOfMessagesVisible`

1. 將警示閾值設定為 **1** （或根據您的期望和 DLQ 流量的其他適當值）。

1. 指定警示關閉時要通知的 Amazon SNS **主題**。此 Amazon SNS 主題可將警示通知傳遞給任何端點類型 (例如電子郵件地址、電話號碼或行動傳呼應用程式)。

您可以使用 CloudWatch Logs 調查導致任何 Amazon SNS 傳遞失敗的例外狀況以及傳送至無效字母佇列的訊息。Amazon SNS 可以在 CloudWatch 中記錄成功和失敗的交付。如需詳細資訊，請參閱[Amazon SNS 行動應用程式屬性](sns-msg-status.md)。

# 設定訂閱的 Amazon SNS 無效字母佇列
<a name="sns-configure-dead-letter-queue"></a>

無效字母佇列是一種 Amazon SQS 佇列，Amazon SNS 將它作為無法成功傳遞給訂閱者訊息的目標。由於用戶端錯誤或伺服器錯誤而無法傳遞的訊息，會保留在無效字母佇列，以供進一步分析或重新處理。如需詳細資訊，請參閱[Amazon SNS 無效字母佇列](sns-dead-letter-queues.md)及[Amazon SNS 訊息傳遞重試](sns-message-delivery-retries.md)。

此頁面說明如何使用 AWS 管理主控台、 AWS 開發套件 AWS CLI、 和 CloudFormation 來設定 Amazon SNS 訂閱的無效字母佇列。

**注意**  
對於 [FIFO 主題](sns-fifo-topics.md)，您可以使用 Amazon SQS 佇列做為 Amazon SNS 訂閱的無效字母佇列。FIFO 主題訂閱使用 FIFO 佇列，而標準主題訂閱則使用標準佇列。

## 先決條件
<a name="dead-letter-queue-prerequisites"></a>

設定無效字母佇列之前，請完成以下先決條件：

1. [建立 Amazon SNS 主題](sns-create-topic.md)，命名為 `MyTopic`。

1. [建立 Amazon SQS 佇列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-create-queue.html)，命名為 `MyEndpoint`，用來做為 Amazon SNS 訂閱的端點。

1. (Skip for CloudFormation) [訂閱 主題的佇列](sns-sqs-as-subscriber.md)。

1. [建立另一個 Amazon SQS 佇列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-create-queue.html)，命名為 `MyDeadLetterQueue`，用作 Amazon SNS 訂閱的無效字母佇列。

1. 若要授予 Amazon SNS 委託人對 Amazon SQS API 動作的存取權，請設定 `MyDeadLetterQueue` 的下列佇列政策。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "sns.amazonaws.com"
         },
         "Action": "SQS:SendMessage",
         "Resource": "arn:aws:sqs:us-east-2:123456789012:MyDeadLetterQueue",
         "Condition": {
           "ArnEquals": {
             "aws:SourceArn": "arn:aws:sns:us-east-2:123456789012:MyTopic"
           }
         }
       }
     ]
   }
   ```

------

## 使用 設定 Amazon SNS 訂閱的無效字母佇列 AWS 管理主控台
<a name="configure-dead-letter-queue-aws-console"></a>

開始本教學課程之前，請先完成下列[先決條件](#dead-letter-queue-prerequisites)。

1. 請登入 [Amazon SQS 主控台](https://console.aws.amazon.com/sqs/)。

1. [建立 Amazon SQS 佇列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-create-queue.html)或使用現有佇列，並記下佇列 **Details** (詳細資訊) 索引標籤上顯示的佇列 ARN，例如：

   ```
   arn:aws:sqs:us-east-2:123456789012:MyDeadLetterQueue
   ```

1. 登入 [Amazon SNS 主控台](https://console.aws.amazon.com/sns/home)。

1. 在導覽面板上，選擇 **Subscriptions (訂閱)**。

1. 在 **Subscriptions** (訂閱) 頁面上，選取現有訂閱，然後選擇 **Edit** (編輯)。

1. 在 **Edit *1234a567-bc89-012d-3e45-6fg7h890123i***(編輯 1234a567-bc89-012d-3e45-6fg7h890123i) 頁面上，展開 **Redrive policy (dead-letter queue)** (再驅動政策 (無效字母佇列)) 區段，然後執行下列動作：

   1. 選擇 **Enable** (啟用)。

   1. 指定 Amazon SQS 佇列的 ARN。

1. 選擇**儲存變更**。

   您的訂閱已設為使用無效字母佇列。

## 使用 AWS SDK 設定 Amazon SNS 訂閱的無效字母佇列
<a name="configure-dead-letter-queue-aws-sdk"></a>

執行此範例之前，請確定您已完成[先決條件](#dead-letter-queue-prerequisites)。

若要使用 AWS SDK，您必須使用登入資料進行設定。如需詳細資訊，請參閱 *AWS SDK和工具參考指南*中的[共享的配置和認證文件](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html)。

以下程式碼範例顯示如何使用 `SetSubscriptionAttributesRedrivePolicy`。

------
#### [ Java ]

**適用於 Java 1.x 的 SDK**  
 GitHub 上提供更多範例。尋找完整範例，並了解如何在 [AWS 程式碼範例儲存庫](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/java/example_code/sns#code-examples)中設定和執行。

```
// Specify the ARN of the Amazon SNS subscription.
String subscriptionArn =
    "arn:aws:sns:us-east-2:123456789012:MyEndpoint:1234a567-bc89-012d-3e45-6fg7h890123i";

// Specify the ARN of the Amazon SQS queue to use as a dead-letter queue.
String redrivePolicy =
    "{\"deadLetterTargetArn\":\"arn:aws:sqs:us-east-2:123456789012:MyDeadLetterQueue\"}";

// Set the specified Amazon SQS queue as a dead-letter queue
// of the specified Amazon SNS subscription by setting the RedrivePolicy attribute.
SetSubscriptionAttributesRequest request = new SetSubscriptionAttributesRequest()
    .withSubscriptionArn(subscriptionArn)
    .withAttributeName("RedrivePolicy")
    .withAttributeValue(redrivePolicy);
sns.setSubscriptionAttributes(request);
```

------

## 使用 設定 Amazon SNS 訂閱的無效字母佇列 AWS CLI
<a name="configure-dead-letter-queue-aws-cli"></a>

開始本教學課程之前，請先完成下列[先決條件](#dead-letter-queue-prerequisites)。

1. 安裝及設定 AWS CLI。如需詳細資訊，請參閱[「*AWS Command Line Interface 使用者指南」*](https://docs.aws.amazon.com/cli/latest/userguide/)。

1. 使用下列 命令。

   ```
   aws sns set-subscription-attributes \
   --subscription-arn arn:aws:sns:us-east-2:123456789012:MyEndpoint:1234a567-bc89-012d-3e45-6fg7h890123i
   --attribute-name RedrivePolicy
   --attribute-value "{\"deadLetterTargetArn\": \"arn:aws:sqs:us-east-2:123456789012:MyDeadLetterQueue\"}"
   ```

## 使用 設定 Amazon SNS 訂閱的無效字母佇列 CloudFormation
<a name="configure-dead-letter-queue-aws-cloudformation"></a>

開始本教學課程之前，請先完成下列[先決條件](#dead-letter-queue-prerequisites)。

1. 將下列 JSON 程式碼複製到名為 `MyDeadLetterQueue.json` 的檔案。

   ```
   {
     "Resources": {
       "mySubscription": {
         "Type" : "AWS::SNS::Subscription",
         "Properties" : {
           "Protocol": "sqs",
           "Endpoint": "arn:aws:sqs:us-east-2:123456789012:MyEndpoint",
           "TopicArn": "arn:aws:sns:us-east-2:123456789012:MyTopic",
           "RedrivePolicy": {
             "deadLetterTargetArn":
               "arn:aws:sqs:us-east-2:123456789012:MyDeadLetterQueue"
           }
         }
       }
     }
   }
   ```

1. 登入 [CloudFormation 主控台](https://console.aws.amazon.com/cloudformation/)。

1. 在 **Select Template** (選擇範本) 頁面中，選擇 **Upload a template to Amazon S3** (上傳範本至 Amazon S3)、選擇您的 `MyDeadLetterQueue.json` 檔案，再選擇 **Next** (下一步)。

1. 在 **Specify Details** (指定詳細資訊) 頁面上，為 **Stack Name** (堆疊名稱) 輸入 `MyDeadLetterQueue`，然後選擇 **Next** (下一步)。

1. 在 **Options** (選項) 頁面上，選擇 **Next** (下一步)。

1. 在 **Review** (檢閱) 頁面上，選擇 **Create** (建立)。

   CloudFormation 開始建立`MyDeadLetterQueue`堆疊，並顯示 **CREATE\$1IN\$1PROGRESS** 狀態。程序完成時， CloudFormation 會顯示 **CREATE\$1COMPLETE** 狀態。