亚马逊SNS和亚马逊SQS有什么区别?

722

何时应该使用SNS而不是SQS,为什么它们总是配套使用?


1
我从您的评论中理解到的流程如下所述...是否正确?发布者-->SNS-->SQL(在队列中保存消息)-->订阅者(目前离线) - friendyogi
5
好的,以下是翻译的结果:标题:队列和通知现在成为了最好的伙伴亚马逊网络服务宣布,他们的消息传递服务 Amazon Simple Queue Service(SQS)和通知服务 Amazon Simple Notification Service(SNS)现在可以无缝协作。通过将 SQS 队列与 SNS 主题相关联,您可以使用订阅、发布和过滤消息等功能来扩展应用程序。这项新功能还可支持多种使用场景,例如分离处理数据的事务性组件、触发工作流或自动化管道以及发送通知。 - Manish Jain
4
你的意思是SQS而不是SQL吗? - elena
这两个服务都有维基百科文章:*Amazon SNS* 和 *Amazon SQS*。 - Peter Mortensen
SQS缺乏发布/订阅功能,而SNS则缺乏竞争消费者:https://learn.microsoft.com/en-us/azure/architecture/patterns/competing-consumers,并且需要SQS来支持死信队列。简而言之,您应该同时使用两者。 - Udi Dahan
显示剩余2条评论
9个回答

986

SNS是一个分布式的发布-订阅系统。当发布者向SNS发送消息时,消息会被推送给订阅者。

SQS是分布式的排队系统。消息不会被推送给接收者。接收者必须从SQS轮询或拉取消息。 消息不能同时被多个接收者接收。任何一个接收者都可以接收、处理并删除消息。其他接收者不会在后续时间内接收相同的消息。 与SNS立即将消息推送给订阅者不同,轮询在SQS中本质上引入了一些延迟。 SNS支持多种终端点,例如电子邮件、短信、HTTP终端和SQS。如果您希望未知数量和类型的订阅者接收消息,则需要使用SNS。

您不必总是将SNS和SQS捆绑在一起。除了SQS以外,SNS可以将消息发送到电子邮件、短信或HTTP终端点。将SNS与SQS配对有其优点。您可能不希望外部服务连接到您的主机(防火墙可能会阻止所有来自外部的连接)。

由于大量消息的存在,您的终端点可能会崩溃。电子邮件和短信可能不是快速处理消息的选择。通过将SNS与SQS捆绑在一起,您可以按自己的节奏接收消息。它允许客户端脱机、容错于网络和主机故障。您还可以实现保证交付。如果您配置SNS将消息发送到HTTP终端点、电子邮件或短信,则多次发送消息失败可能会导致消息丢失。

SQS主要用于解耦应用程序或集成应用程序。消息可以在SQS中存储短暂时间(最长14天)。SNS将多个副本的消息分发给多个订阅者。例如,假设您想将应用程序生成的数据复制到多个存储系统中。您可以使用SNS,并将此数据发送给多个订阅者,每个订阅者将其接收到的消息复制到不同的存储系统(S3、主机上的硬盘、数据库等)。


3
基本上,要实现类似推送通知的功能,建议使用SNS和SQS,这样通过SNS进行的推送将被排队,直到用户准备好从队列中检索它们。是否可以为每个用户创建一个队列? - Nick Ginanto
3
没问题。对于SNS,您可以拥有任意数量的订阅者,并且可以将通知发送到多个队列。 - Srikanth
5
@NickGinanto,按用户排队可能不是您想要的。 您可能希望为每个服务设置一个队列,然后处理特定于用户的消息。 这张图或许能帮助您:https://aws.amazon.com/blogs/aws/queues-and-notifications-now-best-friends/ - Trenton
3
需要翻译的内容:It should probably be noted that as of mid 2018 SQS can trigger lambdas and therefore is more akin to a pubsub in that case.自 2018 年中期起,SQS 可以触发 Lambda,因此在这种情况下更类似于发布-订阅。 - cyberwombat
3
这是我遇到的迄今为止最好、最简明易懂的关于两个AWS服务的解释。 - Yajairo87
显示剩余6条评论

415

以下是两者之间的比较:

实体类型

  • SQS:队列(类似于JMS)
  • SNS:主题(发布/订阅系统)

消息消费

  • SQS:拉取机制 - 消费者从 SQS 拉取消息
  • SNS:推送机制 - SNS 推送消息给消费者

用例

  • SQS:解耦两个应用程序并允许并行异步处理
  • SNS:广播 - 以多种方式处理相同的消息

持久性

  • SQS:如果没有可用的消费者,则在某些(可配置的)持续时间内保存消息(最长两周),因此当消息添加到队列时,消费者不必在线。
  • SNS:无持久性。消息到达时存在的任何消费者都会接收到该消息,并删除该消息。如果没有可用的消费者,则在几次重试后消息将丢失。

消费者类型

  • SQS:所有消费者通常都是相同的,因此以完全相同的方式处理消息(每个消息由一个消费者处理一次,尽管在罕见情况下消息可能会被重新发送)
  • SNS:消费者可能以不同的方式处理消息

示例应用程序

  • SQS:作业框架:将作业提交给SQS,消费方可以异步处理作业。如果作业频率增加,则可以增加消费方数量以提高吞吐量。
  • SNS:图像处理。如果有人将图像上传到 S3 ,则为该图像添加水印,创建缩略图并发送一个谢谢电子邮件。在这种情况下,S3可以将通知发布到一个SNS主题上,并有三个消费方监听它。第一个消费方添加水印,第二个消费方创建缩略图,第三个消费方发送一个谢谢电子邮件。它们都接收相同的消息(图像URL)并并行进行处理。

3
如果没有可用的消费者,则会有重试机制,即使默认值为10次重试。 - Arpit Solanki
2
我不认为“SQS:所有消费者都应该是相同的,因此以完全相同的方式处理消息”是正确的。我曾经使用过SQS,其中两个不同的AWS服务从SQS队列中获取并以自己的方式处理消息(这些不同服务中有不同的应用逻辑)。我错过了什么吗? - nad
1
@nad 我需要了解你的使用情况,但对我来说,两个SQS消费者以非相同的方式处理消息是没有意义的。这是使用SNS的用例。 - Arafat Nalkhande
1
是的,但是谁来删除这条消息呢?难道消费者1、消费者2和消费者3不会一遍又一遍地收到相同的消息吗? - Arafat Nalkhande
谢谢指出这一点...但是那篇medium.com文章发表于2019年5月25日,而这个答案几乎是一年前的2018年6月14日给出的。 - Arafat Nalkhande
显示剩余4条评论

70
你可以将SNS视为传统主题,可以有多个订阅者。对于给定的SNS主题,您可以拥有异构订阅者,包括LambdaSQS等。您还可以使用SNS直接发送短信消息甚至电子邮件。在SNS中需要考虑的一件事是一次只能接收到一条消息(通知),因此无法从批处理中获益。
另一方面,SQS只是一个队列,您可以将消息存储在其中并订阅一个消费者(是的,您可以将N个消费者连接到一个SQS队列,但很快就会变得混乱且难以管理,因为所有消费者都需要至少读取一次消息,所以最好结合使用SNS和SQS来处理此用例,其中SNS将通知推送到N个SQS队列,每个队列只有一个订阅者)。截至2018年6月28日,AWS支持Lambda触发器用于SQS,这意味着您不再需要轮询消息。
此外,您可以在源SQS队列上配置DLQ,在失败的情况下将消息发送到该队列。如果成功,则自动删除消息(这是另一个很好的改进),因此您不必担心已处理的消息会被再次读取,以防您忘记手动删除它们。我建议查看Lambda Retry Behaviour以更好地了解其工作原理。
使用SQS的一个巨大优点是它支持批处理。每个批次最多可以包含10条消息,因此如果100条消息同时到达您的SQS队列,则会启动10个Lambda函数(考虑到Lambda的默认自动缩放行为),并且它们将处理这100条消息(请记住,这是理想情况,实际上可能会有更多的Lambda函数启动,读取少于批处理中的10条消息,但您明白我的意思)。但是,如果您将相同的100条消息发布到SNS,则会启动100个Lambda函数,不必要地增加成本并使用Lambda并发。
但是,如果您仍在运行传统服务器(例如EC2实例),则仍需要轮询消息并手动管理它们。
您还可以使用FIFO SQS队列,它保证消息的传递顺序。SQS FIFO也支持作为Lambda的事件源,截至2019年11月
尽管它们的使用情况有些重叠,但SQS和SNS各有自己的亮点。
如果需要多个订阅者或方便地发送短信/电子邮件,则使用SNS。
如果只需要一个订阅者或批处理很重要,则使用SQS。

将任务分配给许多消费者是 SQS 的主要预期用例。(无论消费者一次检索 1 条消息还是 10 条消息,应用程序控制存在多少个消费者。)它与 SNS 不同,因为 SNS 尝试将每条消息发送到所有订阅者,而 SQS 尝试将消息分区给消费者。 - benjimin

66

AWS SNS是一个发布-订阅网络,在其中订阅者可以订阅话题,并在发布者发布到该话题时接收消息。

AWS SQS是一个队列服务,它将消息存储在队列中。SQS不能传递任何消息,需要外部服务(lambda、EC2等)来轮询SQS并从SQS获取消息。

SNS和SQS可以一起使用,有多种原因。

  1. 可能有不同类型的订阅者,其中一些需要立即传递消息,而其他一些则需要通过轮询将消息保留以供以后使用。请参阅此链接

  2. 扇出模式”。用于异步处理消息。当将消息发布到SNS时,它可以并行地将其分发到多个SQS队列中。在应用程序中并行加载缩略图时,这将非常有用,当图像被发布时。请参阅此链接

  3. 持久性存储。当将要处理消息的服务不可靠时。在这种情况下,如果SNS将通知推送到服务,并且该服务不可用,则通知将丢失。因此,我们可以使用SQS作为持久性存储,然后在以后处理它。


8
您的评论是唯一一个清晰解释如何结合使用SNS和SQS的评论。谢谢! - Andriy
我是AWS的新手,但自回答编写以来有什么变化吗? [https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html](SNS传递重试) Amazon SNS为每个传递协议定义了传递策略。传递策略定义了当发生服务器端错误(订阅的端点所在的系统不可用)时,Amazon SNS如何重试消息的传递。当传递策略耗尽时,Amazon SNS停止重试传递并且丢弃该消息 - 除非死信队列附加到订阅。 - buzztr
@buzztr 3. 没有改变;它指的是 SQS 的消费者不可用。你引用的文档描述了 SNS 的一个新功能,即在尝试完重试后无法将消息传递给消费者(在本例中为 SQS),导致 SNS 将该消息放入专用的 SQS 队列中以处理传输错误。这意味着消息不会完全丢失,而是被保存下来,并可以在稍后通过 SNS 主题重新尝试传输。 - Hans Hermans

37

根据AWS文档:

Amazon SNS允许应用程序通过“推送”机制向多个订阅者发送时间关键消息,从而消除了定期检查或“轮询”更新的必要性。

Amazon SQS是一种消息队列服务,由分布式应用程序通过轮询模型交换消息,并可用于解耦发送和接收组件-而无需每个组件同时可用。

向Amazon SQS队列进行扇出


1
SQS可以“轮询等待消息进来”(类似于推送)。但它仅处理该消息一次,因此不是广播推送。 - rogerdpack

21
以下是AWS主要消息技术(SQS、SNS、+EventBridge)之间的主要区别。为了选择特定的AWS服务,我们应该了解服务提供的功能以及与其他服务的比较。
以下图表总结了该服务的主要相似之处以及差异。 enter image description here

13

简单来说,

  • SNS - 使用推送机制向订阅者发送消息,无需拉取。

  • SQS - 这是一个消息队列服务,由分布式应用程序使用轮询模型交换消息,可用于解耦发送和接收组件。

常见的模式是使用SNS将消息发布到Amazon SQS队列,以可靠地异步发送消息给一个或多个系统组件。

参考来源:Amazon SNS FAQs


1
SQS无法向许多系统发送消息,因为它不能将消息扇出。是的,许多轮询者可以从中拉取消息,但如果其中一个消费者删除了消息,则其他订阅者将无法再次消费相同的消息。如果要实现扇出模式,则应优先选择SNS而不是SQS。此外,如果设置了visibilityTimeout,则在其他系统处理该消息时,其他系统将无法消耗该消息。 - Thales Minussi
2
一种常见的模式是使用SNS将消息发布到Amazon SQS队列,以可靠地异步发送消息到一个或多个系统组件。参考自https://aws.amazon.com/sns/faqs/ - Krunal Barot
1
如果你的意思是(SNS->多个SQS队列),请编辑你的回答,我会很乐意撤销我的投票。按照你的说法,SQS似乎可以扇出。 - Thales Minussi
1
是的..那就是混淆的地方。我已经编辑过了..谢谢 :) - Krunal Barot
这是一个开始,但问题是关于它们的区别等等:“何时使用SNS而不是SQS,为什么它们总是一起使用?”也许更直接地回答这个问题?您可以编辑您的答案(不要包含“编辑:”,“更新:”或类似内容 - 答案应该看起来像今天写的)。 - Peter Mortensen

2
SNS和SQS之间有一些关键区别:
- SNS支持A2A和A2P通信,而SQS仅支持A2A通信。 - SNS是一个发布/订阅系统,而SQS是一个队列系统。通常,您可以通过主题使用SNS将相同的消息发送给多个消费者。相比之下,在大多数场景中,SQS队列中的每条消息只由一个消费者处理。使用SQS时,消息通过长轮询(拉)机制传递,而SNS则使用推送机制立即将消息传递到已订阅的端点。 - SNS通常用于需要实时通知的应用程序,而SQS更适用于消息处理用例。 - SNS不会持久保存消息-它将其交付给存在的订阅者,然后将其删除。相比之下,SQS可以持久保存消息(从1分钟到14天)。
单独使用Amazon SQS和SNS用于不同的用例。但在某些情况下,您可以将它们一起使用。

1
将SQS和SNS耦合的一个原因是用于数据处理流水线。假设你正在生成三种产品,其中B和C都是从同一中间产品A派生而来。对于每种产品(即每个管道段),您需要设置以下内容:计算资源(可能是lambda函数、虚拟机集群或自动缩放的kubernetes job)以生成产品;队列(描述需要执行的工作单元)将工作划分到计算资源上(使每个工作单元仅被处理一次,但不同的工作单元可以并行且异步地处理);新闻源(宣布已经产生的输出)。然后安排B和C的输入队列都订阅A的输出通知。这使得流水线在基础设施级别上成为模块化。而不是有一个生成所有三种产品的单块服务器应用程序,流水线的不同阶段可以利用不同的硬件资源(例如,B阶段需要大量内存,但另外两个阶段可以使用更便宜的硬件/服务来完成)。这也使得更容易迭代一个管道段的开发而不会干扰其他产品的交付。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接