Amazon Simple Notification Service
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

通过将 Amazon SQS 队列作为订阅者,来使用 Amazon SNS 进行系统到系统消息收发

Amazon SNS 与 Amazon Simple Queue Service (Amazon SQS) 紧密协作。这两种服务都能为开发人员带来不同的益处。Amazon SNS 让应用程序通过“推送”机制将紧急消息发送给多个订阅者,并且无需定期检查或“轮询”更新。Amazon SQS 是分布式应用程序用于通过轮询模式来交换消息的消息队列服务,可用于分离各个组成部分的发送和接收而不要求所有组成部分都同时可用。—通过将 Amazon SNS 和 Amazon SQS 配合使用,可以将消息发送到要求立即通知事件的应用程序,也可以在 Amazon SQS 队列中存留消息以供其他应用程序稍后进行处理。

为 Amazon SQS 队列订阅 Amazon SNS 主题时,您可以向该主题发布消息,并且 Amazon SNS 会向已订阅队列发送一条 Amazon SQS 消息。Amazon SQS 消息包括已向主题发布的相关主题和消息,包括有关 JSON 文档中消息的元数据。Amazon SQS 消息与以下 JSON 文档相似。

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

重要

Amazon SNS 当前与 Amazon SQS FIFO 队列不兼容。

此时您可以利用 Amazon SQS 控制台为 Amazon SQS 队列订阅 Amazon SNS 主题(这样操作能够简化流程),从而无需按照下述步骤操作。有关更多信息,请参阅为队列订阅 Amazon SNS 主题

要通过 Amazon SNS 主题向 Amazon SQS 队列发送消息,请执行以下步骤:

要了解如何设置主题以向不同的 AWS 账户中的队列发送消息,请参阅 向不同账户中的 Amazon SQS 队列发送 Amazon SNS 消息

要查看创建向两个队列发送消息的主题的 AWS CloudFormation 模板,请参阅利用 AWS CloudFormation 模板创建向 Amazon SQS 队列发送消息的主题

步骤 1:获取队列的 ARN 和主题

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

您可以使用 Amazon SQS 控制台或 GetQueueAttributesAPI 操作获取队列 ARN。

从 Amazon SQS 控制台获取队列 ARN

  1. 登录 AWS 管理控制台并通过以下网址打开 Amazon SQS 控制台:https://console.amazonaws.cn/sqs/

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

  3. 详细信息选项卡中,复制 ARN 值,然后使用该值订阅 Amazon SNS 主题。

要获取主题 ARN,您可以使用 Amazon SNS 控制台、sns-get-topic-attributes 命令或 GetQueueAttributes API 操作。

从 Amazon SNS 控制台获取主题 ARN

  1. 登录 Amazon SNS 控制台

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

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

步骤 2:为 Amazon SNS 主题授予向 Amazon SQS 队列发送消息的权限

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

获取主题和队列之后,方可为队列订阅主题。如果您尚未创建主题或队列,请您立刻创建。有关更多信息,请参阅创建主题以及Amazon Simple Queue Service 开发人员指南中的创建队列

您可以使用 Amazon SQS 控制台或 SetQueueAttributes API 操作针对队列设置策略。开始前,请确保针对您想要允许向队列发送消息的主题,您已拥有其 ARN。

通过 Amazon SQS 控制台在队列上设置 SendMessage 策略

  1. 登录 AWS 管理控制台并通过以下网址打开 Amazon SQS 控制台:https://console.amazonaws.cn/sqs/

  2. 选择要设置其策略的队列的框,然后依次选择权限选项卡、添加权限

  3. Add a Permission (添加权限) 对话框中,为 Effect (效果) 选择 Allow (Allow),为 Principal (委托人) 选择 Everybody (*) (所有人 (*)),然后从操作下拉列表中选择 SendMessage (发送消息)

  4. 添加允许主题操作的一项条件。选择 Add Conditions (optional) (添加条件 (可选)),对于 Condition (条件) 选择 ArnEquals (Arn 等于),对于 Key (键) 选择 aws:SourceArn,然后对于 Value (值) 粘贴主题 ARN。选择添加条件。框底部将显示新添加条件(可以通过下拉列表查看此条件)。

  5. 选择 Add Permission

如果您要自行创建策略文档,请创建如下策略。该策略允许“我的主题”向“我的队列”发送消息。

{ "Version": "2012-10-17", "Id": "MyQueuePolicy", "Statement": [{ "Sid":"MySQSPolicy001", "Effect":"Allow", "Principal":"*", "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 主题

必须为队列订阅 Amazon SNS 主题后,方可通过主题向队列发送消息。您可以按队列 ARN 指定队列。要订阅主题,您可以使用 Amazon SNS 控制台、sns-subscribe CLI 命令或 Subscribe API 操作。开始前,必须确保您拥有要订阅队列的 ARN。

  1. 登录 Amazon SNS 控制台

  2. 在导航面板上,选择主题

  3. 主题 页上,选择一个主题。

  4. 我的主题页上,在订阅页中,选择创建订阅

  5. 创建订阅页上,在详细信息部分中,执行以下操作:

    1. 验证主题 ARN

    2. 对于协议,选择 Amazon SQS

    3. 对于终端节点,输入 Amazon SQS 队列的 ARN。

    4. 选择创建订阅

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

    一般情况下,您可以在您自己的账户中为您的队列订阅您自己的主题。但是,您还可以通过另一账户为队列订阅主题。如果创建订阅的用户并非队列所有者(例如,如果账户 A 的用户为账户 B 中的队列订阅账户 A 中的主题),则必须对订阅进行确认。有关通过不同账户订阅队列和确认订阅的更多信息,请参阅 向不同账户中的 Amazon SQS 队列发送 Amazon SNS 消息

步骤 4:向用户授予对适当主题和队列操作的权限

您应使用 AWS Identity and Access Management (IAM) 仅允许适当用户发布到 Amazon SNS 主题,以及从 Amazon SQS 队列中读取/删除消息。有关控制 IAM 用户的主题和队列操作的更多信息,请参阅控制用户访问您的 AWS 账户以及Amazon Simple Queue Service 开发人员指南中的控制对 AWS 账户的用户访问

可以采取两种方式控制对主题或队列的访问:

  • 向 IAM 用户或组添加策略。为用户授予主题或队列权限的最简单方式就是创建群组,并为该群组添加适当策略,然后向此群组添加用户。相比较而言,向群组添加或删除用户,比追踪您为单独用户而设定的各项策略要简单得多。

  • 添加策略至主题或队列。如果您想为另一 AWS 账户授予主题或队列权限,那么唯一的方法只有添加策略,而该策略必须具备您授予权限目标账户的主要 AWS 账户。

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

向 IAM 用户或组添加策略

如果您已向 IAM 用户或组添加以下策略,那么您应向该组的用户或成员授予对主题“我的主题”执行 sns:Publish操作的权限。

{ "Version": "2012-10-17", "Statement": [{ "Sid": "AllowPublishToMyTopic", "Effect": "Allow", "Action": "sns:Publish", "Resource": "arn:aws:sns:us-east-2:123456789012:MyTopic" }] }

如果您已添加以下策略至 IAM 用户或组,那么您应向该组的用户或成员授予在队列 MyQueue1 和 MyQueue2 上执行 sqs:ReceiveMessagesqs:DeleteMessage 操作的权限。

{ "Version":"2012-10-17", "Statement":[{ "Sid":"AllowReadDeleteMessageOnMyQueue", "Effect":"Allow", "Action":[ "sqs:ReceiveMessage", "sqs:DeleteMessage" ], "Resource":[ "arn:aws:sns:us-east-2:123456789012:MyQueue1", "arn:aws:sns:us-east-2:123456789012:MyQueue2" ] }] }

向主题或队列添加策略

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

注意

当您允许另一 AWS 账户访问您账户中的资源时,您也就向拥有管理员级访问(通配符访问)的 IAM 用户授予访问该资源的权限。此操作将自动拒绝其他账户中的所有其他 IAM 用户访问您的资源。如果您要向该 AWS 账户中的特定 IAM 用户授予访问您的资源的权限,那么拥有管理员级访问权限的账户或 IAM 用户必须将此项资源的访问权限委派给这些 IAM 用户。有关跨账户委派的更多信息,请参阅 使用 IAM 指南 中的 启用跨账户访问

如果您向账户 123456789012 的主题“我的主题”添加以下策略,那么您同时也是向账户 111122223333 授予在此主题上执行 sns:Publish 操作的权限。

{ "Version":"2012-10-17", "Id":"MyTopicPolicy", "Statement":[{ "Sid":"Allow-publish-to-topic", "Effect":"Allow", "Principal":{ "AWS":"111122223333" }, "Action":"sns:Publish", "Resource":"arn:aws:sns:us-east-2:123456789012:MyTopic" }] }

如果您向账户 123456789012 的队列 MyQueue 添加以下策略,那么您同时也是向账户 111122223333 授予在此队列上执行 sqs:ReceiveMessagesqs:DeleteMessage 操作的权限。

{ "Version":"2012-10-17", "Id":"MyQueuePolicy", "Statement":[{ "Sid":"Allow-Processing-Of-Messages-for-Queue", "Effect":"Allow", "Principal":{ "AWS":"111122223333" }, "Action":[ "sqs:DeleteMessage", "sqs:ReceiveMessage" ], "Resource":[ "arn:aws:sns:us-east-2:123456789012:MyQueue" ] }] }

步骤 5:测试主题的队列订阅

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

利用 Amazon SNS 控制台发布主题

  1. 利用拥有发布主题权限的 AWS 账户或 IAM 用户的凭证,登录 AWS 管理控制台 并通过 https://console.amazonaws.cn/sns/ 打开 Amazon SNS 控制台。

  2. 在导航面板上,选择主题,然后选择发布到主题

  3. 主题框中,输入主题(例如 Testing publish to queue),在消息框中,输入一些文字(例如 Hello world!),然后选择发布消息。界面将显示如下消息:“Your message has been successfully published”(您的消息已成功发布)。

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

  1. 利用拥有查看队列中消息权限的 AWS 账户或 IAM 用户的凭证登录 AWS 管理控制台 并通过 https://console.amazonaws.cn/sqs/ 打开 Amazon SQS 控制台。

  2. 选中订阅主题的队列框。

  3. Queue Action (队列操作) 下拉列表中,选择 View/Delete Messages (查看/删除消息),然后选择 Start Polling for Messages (开始轮询消息)。界面将显示“Notification”类型消息。

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

    { "Type" : "Notification", "MessageId" : "63a3f6b6-d533-4a47-aef9-fcf5cf758c76", "TopicArn" : "arn:aws:sns:cn-north-1:123456789012:MyTopic", "Subject" : "Testing publish to subscribed queues", "Message" : "Hello world!", "Timestamp" : "2012-03-29T05:12:16.901Z", "SignatureVersion" : "1", "Signature" : "EXAMPLEnTrFPa37tnVO0FF9Iau3MGzjlJLRfySEoWz4uZHSj6ycK4ph71Zmdv0NtJ4dC/El9FOGp3VuvchpaTraNHWhhq/OsN1HVz20zxmF9b88R8GtqjfKB5woZZmz87HiM6CYDTo3l7LMwFT4VU7ELtyaBBafhPTg9O5CnKkg=", "SigningCertURL" : "https://sns.cn-north-1.amazonaws.cn/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem", "UnsubscribeURL" : "https://sns.cn-north-1.amazonaws.cn/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:cn-north-1:123456789012:MyTopic:c7fe3a54-ab0e-4ec2-88e0-db410a0f2bee" }
  5. 选择 Close。您已经成功发布到一个主题,该主题向队列发送通知消息。