

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

# 了解如何在 Amazon SQS 中配置死信队列重新驱动
<a name="sqs-configure-dead-letter-queue-redrive"></a>

使用死信队列重新驱动，将死信队列中未使用的消息移到其他目标进行处理。默认情况下，死信队列重新驱动会将消息从死信队列移动到源队列。但是，您还可以将任何其他队列配置为重新驱动目的地，前提是两个队列属于同一类型。例如，如果死信队列是 FIFO 队列，则重新驱动目的地队列也必须是 FIFO 队列。此外，您可以配置重新驱动速度以设置 Amazon SQS 移动消息的速率。

**注意**  
 当消息从 FIFO 队列移动到 FIFO DLQ 时，原始消息的重复数据删除 ID 将替换为原始消息的 ID。这是为了确保 DLQ 重复数据删除不会阻止存储恰好共享重复数据删除 ID 的两条独立消息。

 死信队列按接收顺序重新驱动消息，从最旧的消息开始。但是，目标队列会根据接收消息的顺序摄取重新驱动的消息以及来自其他创建者的新消息。例如，如果创建者在向源 FIFO 队列发送消息的同时从死信队列接收重新驱动的消息，则重新驱动的消息将与创建者的新消息交织在一起。

**注意**  
重新驱动任务会重置保留期。所有重新驱动的消息都被视为新消息，并且系统会为其分配新的 `messageID` 和 `enqueueTime`。

## 使用 Amazon SQS API 为现有标准队列配置死信队列重新驱动
<a name="sqs-configure-dead-letter-queue-redrive-API"></a>

 您可以使用 `StartMessageMoveTask`、`ListMessageMoveTasks` 和 `CancelMessageMoveTask` API 操作配置死信队列重新驱动：


| API 操作 | 说明 | 
| --- | --- | 
|  [https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_StartMessageMoveTask.html](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_StartMessageMoveTask.html)  |  启动异步任务，将消息从指定的源队列移动到指定的目标队列。  | 
|  [https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_ListMessageMoveTasks.html](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_ListMessageMoveTasks.html)  |  获取特定源队列下的最新消息移动任务（最多 10 个）。  | 
|  [https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_CancelMessageMoveTask.html](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/API_CancelMessageMoveTask.html)  |  取消指定的消息移动任务。只有在当前状态为“正在运行”时，才能取消消息移动。  | 

## 使用 Amazon SQS 控制台为现有标准队列配置死信队列重新驱动
<a name="sqs-configure-dead-letter-queue-redrive-console"></a>

1. 打开 Amazon SQS 控制台，网址为。[https://console.aws.amazon.com/sqs/](https://console.amazonaws.cn/sqs/)

1. 在导航窗格中，选择**队列**。

1. 选择已配置为[死信队列](sqs-configure-dead-letter-queue.md)的队列名称。

1. 选择**开始 DLQ 重新驱动**。

1. 在**重新驱动配置**下，对于**消息目标**，执行以下任一操作：
   + 要将消息重新驱动到其源队列，请选择**重新驱动到源队列**。
   + 要将消息重新驱动到其他队列，请选择**驱动到自定义目标**。然后，输入现有目标队列的 Amazon 资源名称 (ARN)。

1. 在**速度控制设置**下，选择以下一个选项：
   + **系统优化** - 以每秒最大消息数重新驱动死信队列消息。
   + **自定义最大速度** - 使用自定义每秒最大消息速率重新驱动死信队列消息。允许的最大速率为每秒 500 条消息。
     + 建议从“自定义最大速度”的较小值开始，并验证源队列不会被消息淹没。在这里，逐渐增加“自定义最大速度”值，继续监控源队列的状态。

1. 配置完死信队列重新驱动后，选择**重新驱动消息**。
**重要**  
Amazon SQS 不支持在将消息从死信队列中重新驱动时筛选和修改消息。  
死信队列重新驱动任务最多可以运行 36 小时。Amazon SQS 支持每个账户最多 100 个活跃的重新驱动任务。

1. 如果要取消消息重新驱动任务，请在队列的**详细信息**页面上，选择**取消 DLQ 重新驱动**。取消正在进行的消息重新驱动时，任何已经成功移至其移动目标队列的消息都将保留在目标队列中。

## 为死信队列重新驱动配置队列权限
<a name="sqs-configure-dead-letter-queue-redrive-permissions"></a>

您可以通过向策略添加权限来授予用户访问特定死信队列操作的权限。死信队列重新驱动所需的最低权限如下：


| 最小权限 | 必需的 API 方法 | 
| --- | --- | 
| 启动消息重新驱动 | [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-dead-letter-queue-redrive.html) | 
| 取消进行中的消息重新驱动 | [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-dead-letter-queue-redrive.html) | 
| 显示消息移动状态 | [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-dead-letter-queue-redrive.html) | 

**为加密队列对（带有死信队列的源队列）配置权限**

使用以下步骤配置死信队列（DLQ）重新驱动的最低权限：

1. 使用 [https://console.aws.amazon.com/iam/](https://console.amazonaws.cn/iam/) 打开 IAM 控制台。

1. 在导航窗格中，选择**策略**。

1. 创建新[https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies_create.html](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies_create.html)并添加以下权限。将该策略附加到将执行重新驱动操作的 IAM [用户](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_users.html)或[角色](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles.html)。
   + DLQ（源队列）的权限：
     + `sqs:StartMessageMoveTask`
     + `sqs:CancelMessageMoveTask`
     + `sqs:ListMessageMoveTasks`
     + `sqs:ReceiveMessage`
     + `sqs:DeleteMessage`
     + `sqs:GetQueueAttributes`
     + `sqs:ListDeadLetterSourceQueues`
     + 指定 DLQ（源队列）的**资源 ARN**（例如，“arn: aws: sqs:::”）。*<DLQ\$1region>* *<DLQ\$1accountId>* *<DLQ\$1name>*
   + 目标队列的权限：
     + `sqs:SendMessage`
     + 指定目标队列`Resource ARN`的（例如，“arn: aws: sqs:”）。*<DestQueue\$1region>:<DestQueue\$1accountId>:<DestQueue\$1name>*
   + KMS 密钥的权限：
     + `kms:Decrypt`（需要，用于解密 DLQ 中的消息。）
     + `kms:GenerateDataKey`（需要，用于加密目标队列中的消息。）
       + `Resource` ARNs:
         + 用于加密 **DLQ**（源队列）中消息的 KMS 密钥的 ARN（例如，“arn: aws: kms::: key/”）。*<region>* *<accountId>* *<SourceQueueKeyId>*
         + 用于加密**目标队列**中消息的 KMS 密钥的 ARN（例如，“arn: aws: kms:: kms:: key/”）。*<region>* *<accountId>* *<DestinationQueueKeyId>*

   访问策略应类似下文：

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "sqs:StartMessageMoveTask",
                   "sqs:CancelMessageMoveTask",
                   "sqs:ListMessageMoveTasks",
                   "sqs:ReceiveMessage",
                   "sqs:DeleteMessage",
                   "sqs:GetQueueAttributes",
                   "sqs:ListDeadLetterSourceQueues"
               ],
               "Resource": "arn:aws:sqs:us-west-1:123456789012:<DLQ_name>",
               "Condition": {
                   "StringEquals": {
                       "aws:ResourceTag/QueueRole": "source"
                   }
               }
           },
           {
               "Effect": "Allow",
               "Action": "sqs:SendMessage",
               "Resource": "arn:aws:sqs:us-west-1:123456789012:<DestQueue_name>",
               "Condition": {
                   "StringEquals": {
                       "aws:ResourceTag/QueueRole": "destination"
                   }
               }
           },
           {
               "Effect": "Allow",
               "Action": [
                   "kms:Decrypt",
                   "kms:GenerateDataKey"
               ],
               "Resource": [
                   "arn:aws:kms:us-west-1:123456789012:key/<SourceQueueKeyId>",
                   "arn:aws:kms:us-west-1:123456789012:key/<DestQueueKeyId>"
               ]
           }
       ]
   }
   ```

------

**使用非加密队列对（带有死信队列的源队列）配置权限**

遵循以下步骤配置处理**未加密的**标准死信队列（DLQ）所需的最低权限。所需的最低权限包括：从死信队列中*接收*、*删除*和*获取*属性，以及向源队列*发送*属性。

1. 使用 [https://console.aws.amazon.com/iam/](https://console.amazonaws.cn/iam/) 打开 IAM 控制台。

1. 在导航窗格中，选择**策略**。

1. 创建新[https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies_create.html](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies_create.html)并添加以下权限。将该策略附加到将执行重新驱动操作的 IAM [用户](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_users.html)或[角色](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles.html)。
   + DLQ（源队列）的权限：
     + `sqs:StartMessageMoveTask`
     + `sqs:CancelMessageMoveTask`
     + `sqs:ListMessageMoveTasks`
     + `sqs:ReceiveMessage`
     + `sqs:DeleteMessage`
     + `sqs:ListDeadLetterSourceQueues`
     + 指定 DLQ（源队列）的**资源 ARN**（例如，“arn: aws: sqs:::”）。*<DLQ\$1region>* *<DLQ\$1accountId>* *<DLQ\$1name>*
   + 目标队列的权限：
     + `sqs:SendMessage`
     + 指定目标队列`Resource ARN`的（例如，“arn: aws: sqs:”）。*<DestQueue\$1region>:<DestQueue\$1accountId>:<DestQueue\$1name>*

   访问策略应类似下文：

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "sqs:StartMessageMoveTask",
                   "sqs:CancelMessageMoveTask",
                   "sqs:ListMessageMoveTasks",
                   "sqs:ReceiveMessage",
                   "sqs:DeleteMessage",
                   "sqs:GetQueueAttributes",
                   "sqs:ListDeadLetterSourceQueues"
               ],
               "Resource": "arn:aws:sqs:us-west-1:111122223333:<DLQ_name>",
               "Condition": {
                   "StringEquals": {
                       "aws:ResourceTag/QueueRole": "source"
                   }
               }
           },
           {
               "Effect": "Allow",
               "Action": "sqs:SendMessage",
               "Resource": "arn:aws:sqs:us-west-1:111122223333:<DestQueue_name>",
               "Condition": {
                   "StringEquals": {
                       "aws:ResourceTag/QueueRole": "destination"
                   }
               }
           }
       ]
   }
   ```

------

## 使用死信队列重新驱动和 VPC 端点访问控制
<a name="using-dlq-redrive-with-vpc-endpoint-access-control"></a>

 当 VPCs 使用`aws:sourceVpc`条件将队列访问权限限制为特定队列时，需要将 Amazon 服务设为例外才能启用死信队列 (DLQ) 重新驱动功能。这是因为在移动消息时，Amazon SQS 服务在您的 VPC 之外运行。

 要允许 DLQ 重新驱动操作，请将 `aws:CalledViaLast` 条件添加到您的队列策略中。这将允许 Amazon SQS 代表您进行 API 调用，同时保持 VPC 限制以便直接访问。

 要同时允许 VPC 受限访问和 DLQ 重新驱动，请执行以下操作：

1. 在队列策略中使用 `aws:CalledViaLast` 条件。

1. 将策略应用于源队列和 DLQ

1. 保持 VPC 限制，以便从其他来源直接访问

 以下是实现了这些要求的策略示例：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "SQSRedriveWithVpcRestriction",
  "Statement": [
    {
      "Sid": "DenyOutsideVPCUnlessAWSService_DestQueue",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "sqs:*",
      "Resource": "arn:aws:sqs:*:111122223333:DestQueue",
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpc": "vpc-1234567890abcdef0"
        },
        "StringNotEqualsIfExists": { 
          "aws:CalledViaLast": "sqs.amazonaws.com"
        }
      }
    },
    {
      "Sid": "DenyOutsideVPCUnlessAWSService_DLQ",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "sqs:*",
      "Resource": "arn:aws:sqs:*:111122223333:Dlq",
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpc": "vpc-1234567890abcdef0"
        },
        "StringNotEqualsIfExists": { 
          "aws:CalledViaLast": "sqs.amazonaws.com"
        }
      }
    }
  ]
}
```

------
+ 请将占位符值替换为实际的值
+ 此策略使用带条件的“拒绝”语句，这比使用“允许”语句更安全
+ `StringNotEqualsIfExists` 运算符负责处理请求上下文中可能不存在条件键的情况。

 或者，您也可以使用 `aws:ViaAWSService` 条件键允许基于服务的访问，同时保持 VPC 限制。此条件键表示请求是否来自 Amazon 服务。以下是使用 `aws:ViaAWSService` 方法代替 `aws:CalledViaLast` 的策略示例：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "SQSRedriveWithVpcRestriction",
  "Statement": [
    {
      "Sid": "DenyOutsideVPCUnlessAWSService_DestQueue",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "sqs:*",
      "Resource": "arn:aws:sqs:*:111122223333:DestQueue",
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpc": "vpc-1234567890abcdef0"
        },
        "BoolIfExists": {
          "aws:ViaAWSService": "false"
        }
      }
    },
    {
      "Sid": "DenyOutsideVPCUnlessAWSService_DLQ",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "sqs:*",
      "Resource": "arn:aws:sqs:*:111122223333:Dlq",
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpc": "vpc-1234567890abcdef0"
        },
        "BoolIfExists": {
          "aws:ViaAWSService": "false"
        }
      }
    }
  ]
}
```

------

带`aws:ViaAWSService`条件的 BoolIfExists 操作员可确保允许来自服务的请求，同时保持 VPC 对直接访问的限制。这可能更易于理解和维护，因为它直接检查请求是否由 Amazon 服务发出，而不是检查上次呼叫的是哪个服务。

 有关 IAM 和资源策略中使用的条件键的更多信息，请参阅“IAM JSON 策略元素：条件”。