亚马逊AWS官方博客

宣布提高吞吐量并为 Amazon SQS FIFO 队列提供死信队列再驱动支持



借助 Amazon Simple Queue Service(Amazon SQS),您可以在任何数量的软件组件之间发送、存储和接收消息。今天,Amazon SQS 为先入先出(FIFO)队列推出了两项新功能:

  • 在选定的 AWS 区域,每个 API 操作的最大吞吐量已提高到每秒 70,000 个事务 (TPS),支持通过批处理每秒发送或接收多达 700,000 条消息。
  • 死信队列(DLQ)再驱动支持,处理在特定重试次数后未使用的消息,其处理方式与标准队列中已有的处理方式类似。

让我们在实践中更深入地了解它们的工作原理。

FIFO 队列吞吐量最高可达 7 万 TPS
FIFO 队列专为要求按消息发送顺序仅处理一次消息的应用程序而设计。虽然标准队列的吞吐量没有数量限制,但是 FIFO 队列在每个 API 操作的 TPS 数量上有上限。

标准队列和 FIFO 队列支持批处理操作,通过单次 API 调用可以发送和接收最多 10 条消息(最大总负载为 256 KB)。这意味着,FIFO 队列每秒最多可以处理其最大吞吐量 10 倍的消息。

2016 年发布之时,FIFO 队列的每个 API 操作最多支持 300 TPS(批处理时每秒 3,000 条消息)。在许多使用案例中,这个数字已经足够了,但是有些客户要求拥有更高的吞吐量。

在 2021 年推出高吞吐量模式后,FIFO 队列的最大吞吐量提高了十倍,并且每个 API 操作最多可处理 3,000 TPS,具体视区域而定。一年后,每个 API 操作的配额翻了一番,最高可达 6,000 TPS。

今年,Amazon SQS 已经提高两次每个 API 操作的 FIFO 队列吞吐量配额,在 8 月份,提高至每个 API 操作最多 9,000 TPS,到了 10 月份,则高达每个 API 操作 18,000 TPS(具体视区域而定)。

今天,Amazon SQS 团队得以再次提高 FIFO 队列吞吐量配额,使得美国东部(弗吉尼亚州北部)、美国西部(俄勒冈州)和欧洲地区(爱尔兰)的客户每个 API 操作最多处理 70,000 TPS(批处理时每秒 700,000 条消息)。这是 FIFO 队列在发布时最大吞吐量的两百多倍。

适用于 FIFO 队列的 DLQ 再驱动支持
有了 Amazon SQS,在特定重试次数后未使用的消息可以自动移至 DLQ。在 DLQ 中,通过对消息进行分析,可以了解这些消息未得到正确处理的原因。有时,使用者应用程序中存在错误或配置错误。有时,消息包含来自源应用程序的无效数据,需要对这些数据进行修复才能再次处理消息。

无论是何种情况,您都可以定义重新处理这些消息的计划。例如,您可以修复使用者应用程序并将所有消息再驱动至源队列。或者,您可以创建一个专用队列,让自定义应用程序接收消息,修复其内容,然后将其发送到源队列。

为了简化将消息移回源队列或其他队列的过程,您可以使用 Amazon SQS 创建再驱动任务。再驱动任务已经可用于标准队列。从今天开始,您还可以为 FIFO 队列启动再驱动任务。

我使用 Amazon SQS 控制台创建了第一个队列(my-dlq.fifo),并将其用作 DLQ。要将消息再驱动回源 FIFO 队列,队列类型必须匹配,因此它也是 FIFO 队列。

然后,我创建了一个源 FIFO 队列(my-source-queue.fifo)来照常处理消息。创建源队列时,我将第一个队列(my-dlq.fifo)配置为 DLQ,并指定 3 作为最大接收条件,满足此条件时,消息将从源队列移动到 DLQ。

控制台屏幕截图。

当使用者收到消息的次数超过此条件指定的次数时,Amazon SQS 会将该消息移至 DLQ。原始消息 ID 会被保留,它可作为追踪该消息的唯一凭证。

为了测试此设置,我使用控制台向源队列发送消息。然后,我使用 AWS 命令行界面(AWS CLI)多次接收消息,而不将其删除。

aws sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/123412341234/my-source-queue.fifo
{
    "Messages": [
        {
            "MessageId": "ef2f1c72-4bfe-4093-a451-03fe2dbd4d0f",
            "ReceiptHandle": "...",
            "MD5OfBody": "0f445a578fbcb0c06ca8aeb90a36fcfb",
            "Body": "My important message."
        }
    ]
}

为了多次收到相同的消息,我等待队列可见性超时中指定的时间过去(默认为 30 秒)。

第三次之后,该消息不在源队列中,因为它已移至 DLQ。当我尝试从源队列接收消息时,列表为空。

aws sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/123412341234/my-source-queue.fifo
{
    "Messages": []
}

为了确认消息已被移动,我对 DLQ 进行了轮询,看看消息是否存在于 DLQ 中。

aws sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/123412341234/my-dlq.fifo
{
    "Messages": [
        {
            "MessageId": "ef2f1c72-4bfe-4093-a451-03fe2dbd4d0f",
            "ReceiptHandle": "...",
            "MD5OfBody": "0f445a578fbcb0c06ca8aeb90a36fcfb",
            "Body": "My important message."
        }
    ]
}

现在消息已移至 DLQ 中,我可以调查消息未被处理的原因(好吧,这次我知道原因),并决定是使用 Amazon SQS 控制台还是使用几个月前推出的新再驱动 API 从 DLQ 再驱动消息。对于此示例,我使用控制台。我回到 Amazon SQS 控制台,选择 DLQ 队列,然后选择开始 DLQ 再驱动

再驱动配置中,我选择将消息再驱动至源队列。或者,我也可以将另一个 FIFO 队列指定为自定义目的地。我使用速度控制设置中的系统优化来再驱动消息,以 Amazon SQS 优化的每秒最大消息数为准。或者,如果 DLQ 中有大量消息,我可以配置自定义的最大每秒消息速率,以避免使用者超载。

控制台屏幕截图。

在开始再驱动任务之前,我可以使用检查消息部分来轮询和检查消息。我已经决定好要做什么,所以我选择了 DLQ 再驱动来开始任务。我只有一条消息要处理,因此再驱动任务很快就完成了。

控制台屏幕截图。

如我所料,该消息已返回源队列并准备再次接受处理。

控制台屏幕截图。

注意事项
除了 GovCloud 区域和位于中国的区域外,所有提供 Amazon SQS 的 AWS 区域均提供对 FIFO 队列的死信队列(DLQ)支持。

在 DLQ 配置中,最大接收次数应介于 1 到 1,000 之间。

使用高吞吐量模式或 DLQ 不会产生额外费用。每个 Amazon SQS 操作都被视作一个请求。单个请求可以发送或接收 1 到 10 条消息,最大总负载为 256 KB。您将根据请求数量付费,标准队列和 FIFO 队列的请求定价不同。

作为 AWS Free Tier 的一部分,标准队列每月的前 100 万次请求不收费,FIFO 队列每月的前 100 万次请求不收费。有关更多信息,请参阅 Amazon SQS 定价

凭借这些更新和吞吐量的增加,您可以使用 FIFO 队列涵盖绝大多数使用案例。

使用 Amazon SQS FIFO 队列可实现高吞吐量、精确一次处理和先入先出交付。

Danilo