

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

# 为 Amazon SQS 队列订阅 Amazon SNS 主题
<a name="subscribe-sqs-queue-to-sns-topic"></a>

要启用 Amazon SNS 主题以将消息发送到 Amazon SQS 队列，请选择以下操作之一：
+ 使用 [Amazon SQS 控制台](https://console.aws.amazon.com/sqs/)，这简化了过程。有关更多信息，请参阅 *Amazon Simple Queue Service 开发人员指南*中的[将 Amazon SQS 队列订阅到 Amazon SNS 主题](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-subscribe-queue-sns-topic.html)。
+ 使用以下步骤：

  1. [获取您要发送消息的目标队列的 Amazon 资源名称（ARN）以及要为队列订阅的主题。](#SendMessageToSQS.arn)

  1. [向 Amazon SNS 主题授予 `sqs:SendMessage` 权限，以便该主题向队列发送消息。](#SendMessageToSQS.sqs.permissions)

  1. [为队列订阅 Amazon SNS 主题。](#SendMessageToSQS.subscribe)

  1. [向 IAM 用户或 AWS 账户 授予适当权限，使之能够发布到 Amazon SNS 主题和阅读来自 Amazon SQS 队列的消息。](#SendMessageToSQS.iam.permissions)

  1. [通过向主题发布消息，并读取来自队列的消息，对其进行测试。](#SendMessageToSQS.test)

要了解如何设置主题以向位于不同的 AWS账户中的队列发送消息，请参阅[将 Amazon SNS 消息发送到不同账户中的 Amazon SQS 队列](sns-send-message-to-sqs-cross-account.md)。

要查看用于创建向两个队列发送消息的主题的 CloudFormation 模板，请参阅[通过以下方式自动发送亚马逊 SNS 到亚马逊 SQS 的消息 AWS CloudFormation](SendMessageToSQS.cloudformation.md)。

## 步骤 1：获取队列的 ARN 和主题
<a name="SendMessageToSQS.arn"></a>

为队列订阅主题时，需要队列 ARN 的副本。同样，为主题授予向队列发送消息的权限时，需要主题 ARN 的副本。

要获取队列 ARN，您可以使用亚马逊 SQS 控制台或 [GetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Query_QueryGetQueueAttributes.html)API 操作。

**从 Amazon SQS 控制台获取队列 ARN**

1. 登录 AWS 管理控制台 并打开 Amazon SQS 控制台，网址为。[https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/)

1. 选定您要获取 ARN 的队列框。

1. 从**详细信息**部分中，复制 ARN 值，然后使用该值订阅 Amazon SNS 主题。

要获取主题 ARN，您可以使用 Amazon SNS 控制台、`[sns-get-topic-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/get-topic-attributes.html)` 命令或 `[GetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Query_QueryGetQueueAttributes.html)` API 操作。

**从 Amazon SNS 控制台获取主题 ARN**

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

1. 在导航面板上，选择要获取其 ARN 的主题。

1. 从**详细信息**部分中，复制 **ARN** 值，这样就可使用该值为 Amazon SNS 主题授予向队列发送消息的权限。

## 步骤 2. 为向 Amazon SQS 队列发送消息的 Amazon SNS 主题授予权限
<a name="SendMessageToSQS.sqs.permissions"></a>

针对能够向队列发送消息的 Amazon SNS 主题，您必须对队列设置策略，以允许 Amazon SNS 主题执行 `sqs:SendMessage` 操作。

获取主题和队列之后，方可为队列订阅主题。如果您尚未创建主题或队列，请您立刻创建。有关更多信息，请参阅[创建主题](sns-create-topic.md)，并参阅《Amazon Simple Queue Service 开发人员指南》**中的[创建队列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/step-create-queue.html)。

要对队列设置策略，您可以使用 Amazon SQS 控制台或 [SetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Query_QuerySetQueueAttributes.html)API 操作。开始前，请确保针对您想要允许向队列发送消息的主题，您已拥有其 ARN。如果要为队列订阅多个主题，策略必须对于每个主题包含一个 `Statement` 元素。

**使用 Amazon SQS 控制台对队列设置 SendMessage 策略**

1. 登录 AWS 管理控制台 并打开 Amazon SQS 控制台，网址为。[https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/)

1. 选择要设置其策略的队列的框，然后依次选择 **Access policy**（访问策略）选项卡、**编辑**。

1. 在 **Access policy**（访问策略）部分中，定义谁可以访问您的队列。
   + 添加允许主题操作的一项条件。
   + 将 `Principal` 设置为 Amazon SNS 服务，如下例所示。
   + 使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) 或 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) 全局条件键来防止[混淆代理](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)场景。要使用这些条件键，请将值设置为主题的 ARN。如果您的队列订阅了多个主题，则可以改用 `aws:SourceAccount`。

   例如，以下策略允许 MyTopic 向发送消息 MyQueue。

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

## 步骤 3. 为队列订阅 Amazon SNS 主题
<a name="SendMessageToSQS.subscribe"></a>

必须为队列订阅 Amazon SNS 主题后，方可通过主题向队列发送消息。您可以按队列 ARN 指定队列。要订阅主题，您可以使用 Amazon SNS 控制台、`[sns-subscribe](https://docs.aws.amazon.com/cli/latest/reference/sns/subscribe.html)` CLI 命令或 `[Subscribe](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html)` API 操作。开始前，必须确保您拥有要订阅队列的 ARN。

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

1. 在导航面板上，选择**主题**。

1. 在**主题** 页上，选择一个主题。

1. 在该{{**MyTopic**}}页面的**订阅**页面中，选择**创建订阅**。

1. 在**创建订阅**页上的**详细信息**部分，执行以下操作：

   1. 验证**主题 ARN**。

   1. 对于 **Protocol**（协议），选择 **Amazon SQS**。

   1. 对于 **Endpoint**（终端节点），输入 Amazon SQS 队列的 ARN。

   1. 选择**创建订阅**。

   确认订阅后，您新建订阅的“**Subscription ID**”将显示其订阅 ID。如果订阅由队列所有者创建，则订阅将自动确认，且订阅立刻可用。

   一般情况下，您可以在您自己的账户中为您的队列订阅您自己的主题。但是，您还可以通过另一账户为队列订阅主题。如果创建订阅的用户并非队列所有者（例如，如果账户 A 的用户为账户 B 中的队列订阅账户 A 中的主题），则必须对订阅进行确认。有关通过不同账户订阅队列和确认订阅的更多信息，请参阅 [将 Amazon SNS 消息发送到不同账户中的 Amazon SQS 队列](sns-send-message-to-sqs-cross-account.md)。

## 步骤 4：向用户授予对适当主题和队列操作的权限
<a name="SendMessageToSQS.iam.permissions"></a>

您应使用 AWS Identity and Access Management (IAM) 仅允许相应的用户向亚马逊 SNS 主题和来自亚马逊 SQS 队列的 read/delete 消息发布消息。有关针对 IAM 用户控制主题和队列操作的更多信息，请参阅 Amazon Simple Queue Service 开发人员指南中的 [将基于身份的策略用于 Amazon SNS](sns-using-identity-based-policies.md) 和 [Amazon SQS 中的 Identity and Access Management](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/UsingIAM.html)。

可以采取两种方式控制对主题或队列的访问：
+ [添加策略至 IAM 用户或群组](#SendMessageToSQS.iam.permissions.user)。为用户授予主题或队列权限的最简单方式就是创建群组，并为该群组添加适当策略，然后向此群组添加用户。相比较而言，向群组添加或删除用户，比追踪您为单独用户而设定的各项策略要简单得多。
+ [添加策略至主题或队列](#SendMessageToSQS.iam.permissions.resource)。如果您想将某个主题或队列的权限授予其他 AWS 账户，那么唯一的方法就是添加一个以 AWS 账户 您想要授予权限的委托人为其委托人的策略。

绝大多数情况下，您应使用第一种方法（通过向群组添加或删除适当用户的方式，向群组添加策略，管理用户权限）。如果您需要向另一账户的用户授予权限，那么应使用第二种方法。

### 添加策略至 IAM 用户或群组
<a name="SendMessageToSQS.iam.permissions.user"></a>

如果您向 IAM 用户或群组添加了以下策略，则需要向该用户或群组中的成员授予对该主题执行`sns:Publish`操作的权限 MyTopic。

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:us-east-2:123456789012:MyTopic"
    }
  ]
}
```

如果您向 IAM 用户或群组添加了以下策略，则需要向该用户或群组中的成员授予对队列 MyQueue 1 `sqs:ReceiveMessage` 和 MyQueue 2 执行和`sqs:DeleteMessage`操作的权限。

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sqs:ReceiveMessage",
        "sqs:DeleteMessage"
      ],
      "Resource": [
        "arn:aws:sqs:us-east-2:123456789012:MyQueue1",
        "arn:aws:sqs:us-east-2:123456789012:MyQueue2"
      ]
    }
  ]
}
```

### 添加策略至主题或队列
<a name="SendMessageToSQS.iam.permissions.resource"></a>

以下策略示例显示如何为主题和队列授予另一账户授权。

**注意**  
当您授予其他人 AWS 账户 访问您账户中某项资源的权限时，也就是向对该资源拥有管理员级访问权限（通配符访问权限）的 IAM 用户授予权限。此操作将自动拒绝其他账户中的所有其他 IAM 用户访问您的资源。如果您要向该 AWS 账户 中的特定 IAM 用户授予访问您的资源的权限，那么拥有管理员级访问权限的账户或 IAM 用户必须将此项资源的访问权限委派给这些 IAM 用户。有关跨账户委派的更多信息，请参阅*使用 IAM 指南*中的[启用跨账户访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/Delegation.html)。

如果您向账户 123456789012 MyTopic 中的主题添加了以下策略，则需要向账户 111122223333 授予对该主题执行操作的权限。`sns:Publish`

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "111122223333"
      },
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:us-east-2:123456789012:MyTopic"
    }
  ]
}
```

如果您向账户 123456789012 MyQueue 中的队列添加了以下策略，则需要授予账户 111122223333 对该队列执行和操作的权限。`sqs:ReceiveMessage` `sqs:DeleteMessage`

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "111122223333"
      },
      "Action": [
        "sqs:DeleteMessage",
        "sqs:ReceiveMessage"
      ],
      "Resource": [
        "arn:aws:sqs:us-east-2:123456789012:MyQueue"
      ]
    }
  ]
}
```

## 步骤 5：测试主题的队列订阅
<a name="SendMessageToSQS.test"></a>

通过发布主题，查看主题向队列发送的消息，可以测试主题的队列订阅情况。

**利用 Amazon SNS 控制台发布主题**

1. 使用有权发布主题的 AWS 账户 或 IAM 用户的证书，登录 AWS 管理控制台 并打开 Amazon SNS 控制台，网址为。[https://console.aws.amazon.com/sns/](https://console.aws.amazon.com/sns/home)

1. 在导航面板上，选择主题，然后选择**发布到主题**。

1. 在**主题**框中，输入主题（例如 **Testing publish to queue**），在**消息**框中，输入一些文字（例如 **Hello world\!**），然后选择**发布消息**。界面将显示如下消息：Your message has been successfully published。

**利用 Amazon SQS 控制台查看来自主题的消息**

1. 使用有权查看队列中消息的 AWS 账户 或 IAM 用户的证书，登录 AWS 管理控制台 并打开 Amazon SQS 控制台，网址为。[https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/)

1. 选择已订阅该主题的 **queue**（队列）。

1. 选择 **Send and receive messages**（发送和接收消息），然后选择 **Poll for messages**（轮询消息）。界面将显示“**Notification**”类型消息。

1. 在**正文**列中，选择**更多详细信息**。“**Message Details**”框包括 JSON 文档，此文档包含您发布主题的主题和消息。消息与以下 JSON 文档相似。

   ```
   {
     "Type" : "Notification",
     "MessageId" : "63a3f6b6-d533-4a47-aef9-fcf5cf758c76",
     "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
     "Subject" : "Testing publish to subscribed queues",
     "Message" : "Hello world!",
     "Timestamp" : "2012-03-29T05:12:16.901Z",
     "SignatureVersion" : "1",
     "Signature" : "EXAMPLEnTrFPa3...",
     "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
     "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c7fe3a54-ab0e-4ec2-88e0-db410a0f2bee"
   }
   ```

1. 选择**关闭**。您已经成功发布到一个主题，该主题向队列发送通知消息。