

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 针对 Amazon SQS 死信队列和死信队列重新驱动问题进行排查
<a name="troubleshooting-dlq-redrive"></a>

以下主题涵盖了 Amazon SQS 死信队列和死信队列重新驱动问题的最常见原因，以及如何进行问题排查。有关更多信息，请参阅《Amazon Knowledge Center 指南》**中的[“如何解决 Amazon SQS DLQ 重新驱动问题？”](https://repost.aws/knowledge-center/sqs-dead-letter-queue-redrive)。

## 死信队列问题
<a name="troubleshooting-dlq-issues"></a>

了解常见的死信队列问题以及如何解决这些问题。

### 使用控制台查看消息可能会导致消息移至死信队列
<a name="sqs-dlq-console"></a>

在控制台中根据相应队列的重新驱动策略查看消息时，Amazon SQS 将进行计数。因此，如果您在控制台中查看某条消息的次数达到相应队列的重新驱动策略中指定的次数，则该消息将被移动到相应队列的死信队列中。

要调整此行为，您可以执行下列操作之一：
+ 针对相应队列的重新驱动策略增大 **Maximum Receives** 设置。
+ 避免在控制台中查看相应队列的消息。

### 死信队列的 `NumberOfMessagesSent` 和 `NumberOfMessagesReceived` 不匹配
<a name="sqs-dlq-number-of-messages"></a>

如果您手动向死信队列发送消息，该消息将被 [`NumberOfMessagesSent`](sqs-available-cloudwatch-metrics.md) 指标捕获。不过，如果因处理尝试失败而发送消息到死信队列，则此指标不会捕获该消息。因此，`NumberOfMessagesSent` 和 [`NumberOfMessagesReceived`](sqs-available-cloudwatch-metrics.md) 的值可能不同。

### 创建和配置死信队列重新驱动
<a name="sqs-dlq-redrive-permissions"></a>

死信队列重新驱动需要您为 Amazon SQS 设置适当的[权限](sqs-configure-dead-letter-queue-redrive.md#sqs-configure-dead-letter-queue-redrive-permissions)，以便接收来自死信队列的消息并将消息发送到目标队列。如果您没有正确的权限，死信队列重新驱动任务可能会失败。您可以查看消息重新驱动任务的状态，以便修复问题，然后重试。

### 标准队列和 FIFO 队列消息故障处理
<a name="sqs-dead-letter-queues-handling-message-failure"></a>

[**标准队列**](standard-queues.md)会在[保留期](sqs-dead-letter-queues.md#understanding-message-retention-periods)到期之前持续处理消息。这种持续处理可以最大限度地减少队列被未使用的消息阻塞的可能性。如果有大量消息未被使用者成功删除，会增加成本并加重硬件负载。为了降低成本，请将处理失败的消息移动到死信队列。

标准队列还支持大量的传输中消息。如果您的大多数消息无法使用且未发送到死信队列，消息的处理速率会变慢。为了保持队列的效率，请确保您的应用程序能够正确处理消息。

[**FIFO 队列**](sqs-fifo-queues.md)通过按顺序使用消息组中的消息，确保仅处理一次。因此，尽管使用者可以继续检索其他消息组中的有序消息，但在被阻塞的队列的消息得到成功处理或移动到死信队列之前，第一个消息组将保持不可用状态。

此外，FIFO 队列支持少量的传输中消息。为了防止您的 FIFO 队列被消息阻塞，请确保您的应用程序能够正确处理消息。

有关更多信息，请参阅[Amazon SQS 消息配额](quotas-messages.md)和 [Amazon SQS 最佳实践](sqs-best-practices.md)。

## 死信队列重新驱动问题
<a name="troubleshooting-dlq-redrive-issues"></a>

了解常见的死信队列重新驱动问题以及如何解决这些问题。

### AccessDenied 权限问题
<a name="accessdenied-permission-issue"></a>

当死信队列重新驱动因为 Amazon Identity and Access Management （IAM）实体没有所需权限而失败时，就会发生 `AccessDenied` 错误。

**错误消息示例：**

```
Failed to create redrive task. Error code: AccessDenied - Queue Permissions to Redrive.
```

发出死信队列重新驱动请求需要以下 API 权限：

**启动消息重新驱动：**
+ 死信队列权限：
  + `sqs:StartMessageMoveTask`
  + `sqs:ReceiveMessage`
  + `sqs:DeleteMessage`
  + `sqs:GetQueueAttributes`
  + `kms:Decrypt`：当死信队列或原始源队列被加密时。
+ 目标队列权限：
  + `sqs:SendMessage`
  + `kms:GenerateDataKey`：当目标队列被加密时。
  + `kms:Decrypt`：当目标队列被加密时。

**取消进行中的消息重新驱动：**
+ 死信队列权限：
  + `sqs:CancelMessageMoveTask`
  + `sqs:ReceiveMessage`
  + `sqs:DeleteMessage`
  + `sqs:GetQueueAttributes`
  + `kms:Decrypt`：当死信队列或原始源队列被加密时。

**显示消息移动状态：**
+ 死信队列权限：
  + `sqs:ListMessageMoveTasks`
  + `sqs:GetQueueAttributes`

### `NonExistentQueue`错误
<a name="nonexistentqueue-error"></a>

当 Amazon SQS 源队列不存在或已被删除时，就会发生 `NonExistentQueue` 错误。进行检查并重新驱动到现有的 Amazon SQS 队列。

**错误消息示例：**

```
Failed: AWS.SimpleQueueService.NonExistentQueue
```

### CouldNotDetermineMessageSource 错误
<a name="couldnotdeterminemessagesource-error"></a>

当您尝试在以下情况下启动死信队列重新驱动时，就会发生 `CouldNotDetermineMessageSource` 错误：
+ 使用 [https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html) API 直接发送到死信队列的 Amazon SQS 消息。
+ 来自配置了 DLQ 的亚马逊简单通知服务 (Amazon SNS) Simple Notification 主题 Amazon Lambda 或函数的消息。

要解决此错误，请在启动重新驱动时选择**重新驱动到自定义目标**。然后，输入 Amazon SQS 队列 ARN，将所有消息从死信队列移动到目标队列。

**错误消息示例：**

```
Failed: CouldNotDetermineMessageSource
```