AWS 提供许多出色的消息传递服务。其中最著名的两项服务是 Amazon Simple Notification Service (SNS) 和 Amazon Simple Queue Service (SQS)。虽然两者的使用方式非常相似,但它们是完全不同的服务。
这篇博文将向您解释相似之处和不同之处,以及如何选择哪种服务。
最后,我将向您展示一些示例用例和一种称为扇出模式的常见事件驱动模式,它结合了 SNS 和 SQS。
亚马逊简单通知服务 (SNS)
Amazon 的 SNS 是一种完全托管的发布和订阅服务。发布者向某个主题发送消息,许多消费者/订阅者订阅该主题。这种关系是多对多的。一个主题可以有多个发布者和多个订阅者。
SNS 的传播方式有多种,有应用到应用(A2A)和应用到人(A2P)。
应用程序到应用程序 (A2A) 目的地是:
- AWS Lambda
- 亚马逊 SQS
- 亚马逊 Kinesis 数据 Firehose
- AWS Event Fork 管道
- HTTP 端点
应用于个人 (A2P) 的目的地包括:
- 短信
- 电子邮件
- 应用内通知
- AWS 聊天机器人
- 寻呼机职责
SNS 性能超强,消息将在几毫秒内发布。
一种常见的模式是扇出模式,它允许将一个事件扇出到 AWS 内的各个订阅者。稍后我将在用例部分更详细地介绍该模式。
SNS 允许标准主题或 FIFO 主题。FIFO 主题具有消息排序,而标准主题则没有。对于 FIFO 主题,限制要严格得多!
Amazon简单队列服务(SQS)
Amazon SQS 是一种完全托管的分布式排队服务。SQS 是基于轮询的,而不是基于推送的。即使它经常看起来像是基于推送的系统,但实际上并非如此。Amazon SQS 通常用于将系统彼此分离并启用异步工作负载。
SQS 的主要模式是让生产者将消息发送到队列。消息将在队列中保留一段定义的时间(默认为 4 天,最长为 14 天)。消费者可以通过检查队列是否有新消息来按计划获取消息。
如果消费者处理了一条消息,如果成功,该消息将被删除。否则,它也可以被其他消费者接收。
SQS 凭借其重新驱动策略提供了许多重试消息的功能。您可以定义多次重试和一个死信队列,以防消息失败。死信队列 (DLQ) 用于处理有错误的消息。如果无法处理消息,它们将被发送到 DLQ 以通知应用程序开发人员有关问题,并可选择保存消息以在原始队列中重播。
SQS 具有多对一关系。您可以从许多不同的生产者向队列发送消息,但只能定义一个消费者。消费者是另一个应用程序,通常是一些计算实例,例如 Lambda、EC2 或 Fargate。
有两种不同类型的队列:标准队列和先进先出 (FIFO) 队列。后者将保持消息的顺序。
有趣的事实:SQS 是 AWS最古老的服务。
差异
本文重点介绍这两种服务之间的差异。
我们了解到,两种服务都以某种方式处理消息。两种服务都能够实现更好的解耦。后端 API 和后台逻辑的执行是松散耦合的,不再相互关联。
但也有显著的差异。让我们来看看它们。
基于推送和轮询
主要区别在于服务的基础。SQS 是基于轮询的服务,而 SNS 是基于推送的服务。
这意味着 SNS 只是将所有消息转发给您订阅的消费者,而 SQS 则将消息保存在队列中并等待它们被接收。这在各个方面都是一个显著的区别。例如,SQS 架构中的延迟稍高一些,因为仍然需要考虑轮询。另一方面,由于消息在短时间内得到正确保存,因此 SQS 的持久性和可靠性要好得多。
多对多与多对一(消费者数量)
第二个区别是关系类型。两种服务都可以从不同的生产者接收消息。这意味着两种服务都具有多对多关系。
主要区别在于 SNS 可以拥有很多订阅者,而 SQS 只能有一个消费者。
SNS 订阅者目前的上限SNS 订阅者目前的上限是每个主题 12,500,000 名订阅者。这个上限非常高!这意味着您可以拥有许多消费者来处理您的消息。
而 SQS 只能有一个消费者。该消费者负责处理该消息,然后删除该消息。
消费者类型
SNS 可以将消息直接发送到应用程序,也可以同时发送到个人。这意味着它支持各种不同的消费者类型。
SNS 可以发送到许多不同的目的地。这些目的地包括:
应用程序到应用程序 (A2A) 目的地是:
- AWS Lambda
- 亚马逊 SQS
- 亚马逊 Kinesis 数据 Firehose
- AWS Event Fork 管道
- HTTP 端点
应用于个人 (A2P) 的目的地包括:
- 短信
- 电子邮件
- 应用内通知
- AWS 聊天机器人
- 寻呼机职责
另一方面,SQS 消息通常会使用 SQS API 来获取。因此,每个支持 AWS SDK 的客户端都可以使用它。通常,队列中的消息将从 AWS Lambda 中获取,因为 SQS 和 Lambda 有本机集成。但也可以简单地使用 SQS API 获取和删除消息。您也可以从本地 PC 上执行此操作 。
持久性
SQS 中的消息将被保存一段时间。这称为保留期。保留期可以是 1 分钟到 14 天,默认值为 4 天。如果未在该时间范围内拾取消息,则该消息将被自动删除。
然而,在SNS中,不存在持久性。无法保证消息一定会被传递。如果没有消费者,则不会传递消息。
这会对可靠性产生很大影响。例如,如果消费者在 SNS 中不可用,则消息将不会被传递。或者,如果消费者没有成功结束,则消息将消失。SQS 对此增加了很大的可靠性。扇出模式可用于将两者结合起来,但稍后会详细介绍该主题。
可靠性-重试
SQS 可以添加重试策略。此策略定义在将失败的消息移至死信队列 (DLQ) 之前应重试多少次。DLQ 处理失败的消息。例如,您可以将失败的消息保存在存储桶中并通知开发人员。
当客户端发生故障时, SNS 不提供重试。如果消费者不可用或消费者无法处理消息(例如推送通知无法发送),则无法重复发送消息。这是由于 SNS 的异步特性。
批处理
SQS 允许您将多条消息批量处理为一条。您可以定义参数batch_size。标准队列的批处理大小最大为 10,000 条记录,FIFO 队列的批处理大小最大为 10 条记录。
SNS 每次只能处理一条消息,因此无法进行批处理。
何时使用什么
我现在什么时候应该使用 SNS,什么时候应该使用 SQS?
一些一般建议:
以下情况请使用 SNS:
- 您有很多订阅者
- 您需要向消费者发送短信、电子邮件或应用程序通知
- 您想使用扇出模式同时向许多订阅者发送消息(稍后会详细介绍)
以下情况请使用 SQS:
- 您只需要一个订阅
- 持久性和错误处理非常重要(每条消息都需要传递)
- 你需要批量处理你的请求
- 你只想解耦你的应用程序并启用异步后台处理
使用案例
让我们看一些示例用例。
社交网络
CloudWatch 警报:
会触发警报,您想要向 10 个不同的电子邮件地址发送消息,并向一些手机发送短信。持久性、批处理和重试并不重要。
应用内通知
一位新用户在您的新社交媒体应用程序上关注了您。您想通知该用户。
新加坡优质服务
后台处理
您的应用程序正在同步执行所有任务,用户需要等待您的 API 返回。通过添加 SQS 队列,您可以运行后台任务并解耦整个应用程序。
批处理
您需要同时处理大量消息。SQS 可以通过批量处理所有消息来解决这个问题。
举个例子:
您主持了一场创业秀,同时获得了大量投票。您需要处理这些投票。您的 API 不可能处理所有这些投票,而且您也不希望用户等待处理这些投票所需的时间。
您可以使用 SQS 来实现这一点。当用户投票时,您的 API 会向 SQS 发送一条消息。您的 API 会向最终用户返回 200 OK,最终用户会获得超快的响应。
实际业务逻辑是分离的。SQS 和 Lambda 将处理其余部分。在这种情况下,许多消息将被批处理在一起,并且将生成许多 lambda 函数。这就是可扩展性。
SNS与SQS组合-扇出模式
到目前为止,我们在文章中将 SNS 和 SQS 视为两种不同的服务。有一种常见的模式称为结合这两种服务的模式。
它被称为扇出模式。
扇出模式描述了一种场景,即发布到 SNS 的消息将同时发送到多个端点。在这种模式下,一条消息可能会触发多次执行。这允许异步处理。
例如:
用户将图片上传到您的应用程序。当发生这种情况时,您希望启动几个后台进程。应该发生以下事情:
- 开始图像识别并创建标题
- 处理图像并创建缩略图
- 通知用户
所有这些过程都可以在后台同时运行。
另一个例子可能是社交媒体网络。
对于发布的每篇文章都应采取多项措施。地点:
- SQS 队列 1:将帖子翻译成不同的语言
- SQS 队列 2:将帖子转换为音频
- SQS 队列 3:更新用户统计信息(帖子数量)
- 电子邮件:通知关注者有关新帖子的信息
- 应用程序内:通知关注者有关新帖子的信息
问题
当人们开始学习 SNS 和 SQS 时,我经常听到人们问很多问题。让我们来看看一些最常见的问题。
我何时应该使用SNS而不是SQS?
社交网站:
- 多个接收器
- 接收者类型为电子邮件、短信或应用内通知
- 需要立即转发消息
服务品质保证:
- 可靠性很重要
- 只有一个消费者
- 复杂的重试和错误处理
- 消息需要一段时间才能收到,但不会立即收到
还有什么其他的选择?
值得一提的替代方案是EventBridge。有些用例中 SNS 或 EventBridge 的选择会重叠。EventBridge 允许您将事件发送到特殊事件总线,而 EventBridge 将您的事件转发到 SNS、SQS、Lambda 等服务。
其中一个主要区别是 EventBridge 允许基于整个事件进行路由和过滤。此外还有许多不同的限制,例如每个事件规则 5 个目标。
另一种常见的消息服务是Kinesis。Kinesis用于处理和分析流数据。
何时使用Kinesis、SNS和SQS?
运动:
- 持续的数据流
- 数据需要处理或分析
- 复杂的实时要求
社交网站:
- 多个接收器
- 接收者类型为电子邮件、短信或应用内通知
- 需要立即转发消息
服务品质保证:
- 可靠性很重要
- 只有一个消费者
- 复杂的重试和错误处理
- 消息需要一段时间才能收到,但不会立即收到
SQS是推送还是轮询?
SQS 是一种轮询服务。消费者轮询消息。即使您将 EventSourceMapping 与 AWS Lambda 结合使用。lambda 仍会轮询多次并收到大量空响应。
如果您有许多需要频繁轮询的队列,那么 SQS 的成本可能会变得非常昂贵。
哪些目标可用于SQS?
SQS 可以与许多不同的目标一起使用。所有可以调用 AWS API 的系统都可以从队列中接收和删除消息。
SQS 通常与以下工具结合使用:
- AWS Lambda
- 亚马逊 ECS
- 亚马逊 EC2
- 亚马逊 SNS
但您可以将它与几乎所有现有的系统一起使用。
是SNS推送还是投票?
SNS 是一个推送系统。它根本不会保留消息,而是直接将其推送给消费者。
可以使用SNS进行推送通知吗?
是的,可以在 iOS 和 Android 上使用 SNS 进行推送通知。
最后的话
本文介绍了 AWS 服务 Amazon Simple Queue Service (SQS) 和 Amazon Simple Notification Service (SNS)。这些服务构成了许多分布式和解耦应用程序的基础。该服务已经存在很多年了,是 AWS 的主要支柱之一。使用这些服务构建可靠且高性能的应用程序至关重要。