Amazon SQS 工作原理

该博文主要为 Amazon SQS 官方文档的机器翻译版本,另外在此基础上做了些许补充、修改。

一、Amazon SQS 基本架构

1.1.分布式队列

分布式消息传送系统有三个主要组成部分:分布式系统的组件、队列(分布在 Amazon SQS 服务器上)以及队列中的消息。

在下面的情况下,您的系统具有多个创建器(向队列发送消息的组件)以及使用者(从队列接收消息的组件)。队列(保存从 A 到 E 的消息)在多个 Amazon SQS 服务器上冗余存储消息。
在这里插入图片描述

1.2.消息生命周期

以下场景介绍 Amazon SQS 消息在队列中从创建到删除的整个生命周期。
在这里插入图片描述
(1) 创建者 (Component 1) 将 Message A 发送到一个队列,该消息在 Amazon SQS 服务器间冗余分布。

(2)使用者 (Component 2) 准备好处理消息时,就从队列使用消息,然后返回 Message A。在处理 Message A 期间,它仍保留在队列中,并且在可见性超时期间不返回至后续接收请求。

(3)使用者 (Component 2) 从队列中删除 Message A,以阻止该消息在可见性超时过期后被再次接收和处理。

注意:
Amazon SQS 会自动删除在队列中已过了最大消息保存期的消息。默认的消息保存期为 4 天。不过,您可使用 SetQueueAttributes 操作将消息保存期设为介于 60 秒和 1209600 秒 (14 天) 之间的值。


二、队列类型

Amazon SQS消息队列分为 标准队列 和 FIFO队列。下表概括了标准队列和 FIFO 队列的功能及区别,后面有更详细的队列说明。

标准队列FIFO队列
无限吞吐量— 标准队列的每个 API 操作每秒支持接近无限的 API 调用 (SendMessage、ReceiveMessage,或者DeleteMessage)。
至少一次传递— 至少传送一次消息,但偶尔会传送消息的多个副本。
尽可能有序— 偶尔会按不同于其发送时的顺序传递。
高吞吐量— 如果您使用的是批处理,FIFO 队列的每个 API 方法每秒最多支持 3000 条消息 (SendMessageBatch、ReceiveMessage,或者DeleteMessageBatch)。每秒 3000 条消息代表 300 条 API 调用,每条调用包含 10 条消息的批处理。要申请提高配额,请提交支持请求。在不使用批处理的情况下,FIFO 队列的每个 API 方法(SendMessage、ReceiveMessage 或 DeleteMessage)每秒最多支持 300 个 API 调用。
确切一次处理— 消息传递一次并在使用者处理并删除它之前保持可用。不会将重复项引入到队列中。
先进先出交付— 严格保持消息的发送和接收顺序。
在这里插入图片描述在这里插入图片描述
当吞吐量很重要时,请在应用程序之间发送数据,例如:
  • 将实时用户请求从密集型后台工作中分离:让用户在调整媒体大小或对媒体编码时上传媒体。
  • 将任务分配给多个工作程序节点:处理大量信用卡验证请求。
  • 将消息分批以便进一步处理:计划要添加到数据库的多个条目。
当事件的顺序重要时,请在应用程序之间发送数据,例如:
  • 确保按正确的顺序运行用户输入的命令。
  • 通过按正确的顺序发送价格修改来显示正确的产品价格。
  • 防止学员在注册账户之前参加课程。

2.1.标准队列

Amazon SQS 消息队列默认为标准队列,标准队列的每个 API 操作(SendMessage、ReceiveMessage 或 DeleteMessage)每秒支持接近无限的 API 调用(详见与消息相关的配额-消息吞吐量)。标准队列支持至少一次消息传递。但是,由于存在允许近乎无限吞吐量的高度分布式架构,偶尔会有一条消息的多个副本不按顺序传送。标准队列会尽最大努力进行排序,保证了消息大致按其发送的顺序进行传送。

(1)消息传递

标准队列会尽量保持消息顺序,但可能有一条消息的多个副本可能不按顺序传送。如果您的系统需要保留订单,我们建议您使用FIFO(先进先出)队列,或者在每条消息中添加排序信息,以便在收到消息后对其重新排序。

(2)至少一次传递

Amazon SQS 会在多台服务器上存储消息的副本,以实现冗余和高可用性。在极少数情况下,当您接收或删除消息时,存储消息副本的某台服务器可能不可用。

如果出现这种情况,则该不可用服务器上的消息副本将不会被删除,并且您在接收消息时可能会再次获得该消息副本。将应用程序设计为幂等应用程序 (多次处理同一消息时,它们不应受到不利影响)。

2.2.FIFO队列

FIFO(first in first out)队列即为先进先出队列。FIFO 队列改进并补充了标准队列。此队列类型最重要的特性是先进先出配送和确切一次处理:

  • 发送和接收消息的顺序严格保持一致;一条消息传送一次后就保持可用,直到使用者处理并删除它为止。
  • 不会将重复项引入到队列中。

此外,FIFO 队列支持消息组,该组允许一个队列中存在多个有序的消息组。FIFO 队列中的消息组数量没有限额。

FIFO队列的每个 API 操作(SendMessage、ReceiveMessage 或 DeleteMessage)无法支持每秒接近无限的 API 调用。详见与消息相关的配额-消息吞吐量

(1)FIFO 传送逻辑

发送消息

如果多条消息连续发送到 FIFO 队列(每条消息具有不同的消息重复数据删除 ID),Amazon SQS 将存储消息并确认传输。然后,可按传输每条消息的确切顺序接收和处理消息。

在 FIFO 队列中,消息基于消息组 ID 进行排序。如果多台主机(或同一主机上的不同线程)将具有相同消息组 ID 的消息发送到 FIFO 队列,Amazon SQS 将按消息到达以供处理的顺序存储消息。要确保 Amazon SQS 保留发送和接收消息的顺序,每位创建者应使用唯一的消息组 ID 来发送其所有消息。

FIFO 队列逻辑仅应用于每个消息组 ID。每个消息组 ID 代表 Amazon SQS 队列中不同的有序的消息组。对于每一个消息组 ID,所有消息的发送和接收均严格遵循一定的顺序。但是,具有不同的消息组 ID 值的消息可能不会按顺序发送和接收。您必须将消息组 ID 与消息关联。如果您未提供消息组 ID,此操作将失败。如果需要一组有序的消息,请为要将消息发送到 FIFO 队列提供相同的消息组 ID。

接收消息

您无法请求接收具有特定消息组 ID 的消息。

当接收来自具有多个消息组 ID 的 FIFO 队列的消息时,Amazon SQS 会首先尝试尽可能多地返回具有相同消息组 ID 的消息。这时其他使用者能处理具有不同消息组 ID 的消息。

注意:
可使用 MaxNumberOfMessages 操作的 ReceiveMessage 请求参数在单次调用中接收多达 10 条消息。这些消息将保留其 FIFO 顺序且可具有相同的消息组 ID。因此,如果具有相同消息组 ID 的消息少于 10 条,则您可接收来自属于 10 条消息的同一批中其他消息组 ID 的消息,但仍按 FIFO 顺序。

多次重试

FIFO 队列允许生产者或使用者尝试多次重试:

  • 如果生产者检测到失败SendMessage操作时,它可以使用相同的消息重复数据消除 ID,根据需要重试发送多次。假设创建者在重复数据消除间隔过期之前至少收到一个确认,多次重试既不会影响邮件的排序,也不会引入重复项。
  • 如果使用者检测到失败ReceiveMessage操作,它可以根据需要重试次数,使用相同的接收请求尝试 ID。假设使用者在可见性超时到期之前至少收到一个确认,多次重试不会影响消息的排序。
  • 当您收到具有消息组 ID 的邮件时,除非您删除该邮件或其变为可见,否则不会返回同一消息组 ID 的其他消息。

(2)确切一次处理

与标准队列不同,FIFO 队列不会引入重复消息。FIFO 队列可帮助您避免向队列发送重复消息。如果您重试SendMessage操作时,Amazon SQS 不会将任何重复消息引入队列。

要配置重复数据删除,必须执行以下操作之一:

  • 启用基于内容的重复数据删除。这将指示 Amazon SQS 使用 SHA-256 哈希通过消息的正文(而不是消息的属性)生成消息重复数据删除 ID。
  • 为消息显式提供消息重复数据删除 ID (或查看序列号)。

附1:与消息相关的配额

配额描述
批处理消息 ID批处理消息 ID 可以包含最多 80 个字符。可以使用以下字符:字母数字符、连字符 (-)和下划线(_)。
消息属性一条消息可以包含最多 10 个元数据属性。
消息批请求一个消息批请求中最多可包含 10 条消息。
消息内容消息可以仅包含 XML、JSON 和非格式化的文本。允许以下 Unicode 字符:#x9 、 #xA 、 #xD 、 #x20 至 #xD7FF 、 #xE000 至 #xFFFD 、 #x10000 至 #x10FFFF。此列表中未包含的任何字符将被拒绝。
消息组 ID处理积压的消息,以避免积压大量具有相同消息组 ID 的消息。
消息保留默认情况下,消息将保留 4 天。最小值为 60 秒 (1 分钟)。最大值为 1209600 秒 (14 天)。
消息吞吐量
标准队列的每个 API 操作(SendMessage、ReceiveMessage 或 DeleteMessage)每秒支持接近无限的 API 调用。
FIFO 队列:
  • 在不使用批处理的情况下,FIFO 队列的每个 API 方法(SendMessage、ReceiveMessage 或 DeleteMessage)每秒最多支持 300 个 API 调用。
  • 如果您使用批处理,FIFO 队列的每个 API 方法每秒最多支持 3000 条消息(SendMessageBatch、ReceiveMessage,或者DeleteMessageBatch)。3000 条消息代表 300 个 API 调用,每个调用带有包含 10 条消息的一个批处理。
    FIFO 队列的高吞吐量:
  • 不使用批处理 (SendMessage、ReceiveMessage, 和DeleteMessage),则 FIFO 队列的高吞吐量每个 API 方法每秒最多支持 3000 条消息。为了获得最大吞吐量,请增加用于未进行批处理的邮件的消息组 ID 数。
  • 您可以使用批处理 API(SendMessageBatch和DeleteMessageBatch)。每秒 30 000 条消息代表 3000 条 API 调用,每个调用带有包含 10 条消息的一个批处理。为了在使用时达到最大吞吐量SendMessageBatch和DeleteMessageBatch,则批处理请求中的所有消息必须使用相同的消息组 ID。

    * 注意
    以上配额可在以下AWS区域:
  • 美国东部 (俄亥俄)
  • 美国东部 (弗吉尼亚北部)
  • 美国西部 (俄勒冈)
  • 欧洲(爱尔兰)
    在所有其他AWS区域,每个 API 操作的最大吞吐量为每秒 1500(无批处理)或 15000(使用批处理)消息。
消息定时器消息的默认(最小)延迟为 0 秒。最长为 15 分钟。
消息大小最小消息大小为 1 字节 (1 个字符)。最大消息大小为 262144 字节 (256 KB)。
消息可见性超时消息的默认可见性超时为 30 秒。最短值为 0 秒。最长时间为 12 小时。
策略信息最大配额为 8192 个字节、20 个语句、50 个委托人或 10 个条件。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Amazon SQS(简单队列服务)是一种完全托管的消息队列服务,可用于在分布式应用程序之间传递消息。AWS SDK for Java 提供了 Amazon SQS 的开发工具包,使您可以轻松地与 Amazon SQS 进行交互并发送和接收消息。下面是使用 AWS SDK for Java 与 Amazon SQS 交互的步骤: 1. 配置 AWS 访问凭证:在使用 AWS SDK for Java 之前,您需要配置 AWS 访问凭证。访问凭证包括 AWS 访问密钥 ID 和秘密访问密钥。您可以使用 AWS 身份和访问管理(IAM)创建和管理这些凭证。 2. 创建 Amazon SQS 客户端:使用 AWS SDK for Java 创建 AmazonSQSClient 对象,以便与 Amazon SQS 服务进行交互。 ``` AmazonSQS sqs = AmazonSQSClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) .withRegion(Regions.US_EAST_1) .build(); ``` 3. 创建队列:使用 AmazonSQS 对象的 createQueue() 方法创建一个新的队列,并将其命名为您选择的名称。 ``` CreateQueueRequest create_request = new CreateQueueRequest(queueName); String myQueueUrl = sqs.createQueue(create_request).getQueueUrl(); ``` 4. 发送消息:使用 AmazonSQS 对象的 sendMessage() 方法向队列发送消息。 ``` SendMessageRequest send_msg_request = new SendMessageRequest() .withQueueUrl(myQueueUrl) .withMessageBody("hello world") .withDelaySeconds(5); sqs.sendMessage(send_msg_request); ``` 5. 接收消息:使用 AmazonSQS 对象的 receiveMessage() 方法从队列中接收消息。 ``` ReceiveMessageRequest receive_request = new ReceiveMessageRequest() .withQueueUrl(myQueueUrl) .withWaitTimeSeconds(20); List<Message> messages = sqs.receiveMessage(receive_request).getMessages(); for (Message message : messages) { // 处理消息 } ``` 6. 删除消息:使用 AmazonSQS 对象的 deleteMessage() 方法从队列中删除已处理的消息。 ``` String messageReceiptHandle = message.getReceiptHandle(); sqs.deleteMessage(new DeleteMessageRequest(myQueueUrl, messageReceiptHandle)); ``` 这些是使用 AWS SDK for Java 与 Amazon SQS 进行交互的基本步骤。您可以根据需要进行调整,以满足您的特定应用程序需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值