关于 SQS 的一些我不知道的事

发布于 作者:

Things I Didn't Know About SQS image

说到队列,AWS SQS 服务是一个 **绝佳** 的选择。它非常便宜,非常可靠,而且扩展性比我们大多数人需要的都要高。

总的来说,我喜欢任何我不必自己管理的服务。大多数 AWS 托管服务都很昂贵。SQS 是为数不多的几个非常实用的服务,而且价格非常实惠。

但是,有一些关键的区别你需要知道!以下每个细节都曾让我吃过亏。以下是一些关于 SQS 的细节,你应该知道!

可见性超时

SQS 队列的一个独特之处是可见性超时。

我们大多数人可能已经习惯于不用考虑这个问题——当我们在 Laravel 队列工作程序中获得一项作业时,其他队列工作程序不会接手该作业。

SQS 的工作方式略有不同。假设我们的可见性超时设置为 10 秒。如果我们的队列工作程序花费超过 10 秒来处理作业,SQS 将使该作业再次可见。这意味着另一个队列工作程序可能会接手该作业!

因此,我们需要确保我们的可见性超时设置得比完成作业所需的时间 **更长**。

可见性超时可以设置为每个 SQS 队列的默认值,也可以设置为每个作业的单独值。你甚至可以延长已存在作业的可见性超时。

Laravel 不会为你设置可见性超时,因此最好设置一个高于处理作业所需时间的默认值。

有一个 "hack" 可以用来延长作业的可见性超时!你可以调用 release() 方法,**确保设置了延迟**。

对于 SQS 队列驱动程序,这会 设置可见性超时。如果你有一个特定的作业,可能需要比默认可见性超时更长的时间,你可以在作业的早期调用此方法(并设置延迟!)以增加可见性超时。这将给你的作业更多时间来处理,然后再被设置为可见,以便其他队列工作程序接手。

public function handle() {
// Increase visibility timeout for this job
// to one minute
$this->release(60);
 
// Continue on with the job...
}

如果你没有设置延迟,可见性超时将为零,这会立即使作业在 SQS 队列中可见——这可能不是你想要的!

长轮询和短轮询

SQS 的 API 都是基于 HTTP 的。这意味着当我们的队列工作程序轮询 SQS 以获取新作业时,它正在向 SQS API 发出 HTTP 请求。

默认情况下,这会进行 "短轮询"——如果在发出 HTTP 请求时没有可用的作业,SQS 会立即返回一个空响应。

长轮询允许你将一个 HTTP 请求保持打开一定时间。在 HTTP 请求保持打开状态时,SQS 可以随时向队列工作程序发送作业。

Laravel 不会进行任何长轮询,但这里有一点很重要。

如果你使用 SQS 队列驱动程序,你可能会发现某些作业需要一段时间才能处理完成——就好像队列工作程序找不到新的作业一样。这与 SQS 在 AWS 中的扩展方式有关。

以下是来自 SQS 文档 的相关内容。

使用短轮询,ReceiveMessage 请求仅查询服务器的一个子集(基于加权随机分布),以查找可用于包含在响应中的消息。即使查询未找到任何消息,Amazon SQS 也会立即发送响应。

使用长轮询,ReceiveMessage 请求会查询所有服务器以查找消息。Amazon SQS 在收集到至少一条可用消息后发送响应,直到达到请求中指定的消息最大数量。仅当轮询等待时间到期时,Amazon SQS 才会发送空响应。

事实证明,使用长轮询,我们更有可能更快地获得作业,因为它会轮询所有可能包含我们作业的 SQS 服务器!

但是,Laravel 默认情况下不支持长轮询。幸运的是,我们可以采取一些措施。在上面链接的文档的底部有一个小提示。

当 ReceiveMessage 请求的 WaitTimeSeconds 参数以以下两种方式之一设置为 0 时,会发生短轮询。

  • ReceiveMessage 调用将 WaitTimeSeconds 设置为 0。
  • ReceiveMessage 调用没有设置 WaitTimeSeconds,但队列属性 ReceiveMessageWaitTimeSeconds 设置为 0。

Laravel 不会执行上面的第一条——它不会在轮询新作业时通过设置 WaitTimeSeconds 来显式启用长轮询。

但是,如果我们将 SQS 队列的默认 ReceiveMessageWaitTimeSeconds 参数设置为大于 0,长轮询就会在 SQS 端启用!虽然 Laravel 队列工作程序不会等待 ReceiveMessageWaitTimeSeconds 的完整值(它会等待 AWS PHP SDK 为发出 HTTP 请求设置的默认超时时间),但这仍然会触发 SQS 检查所有服务器,就好像它正在进行长轮询一样,这意味着我们更有可能从我们的 SQS 队列中更快地获得作业。

这是一件小事,但确实帮助我解决了我偶尔对 SQS 队列的烦恼!

保证和作业顺序

SQS 有 2 种类型

  1. 标准
  2. FIFO(先进先出)

标准 SQS

标准 SQS 是我们大多数人使用的。它保证 "至少一次传递",除此之外别无其他。这意味着 2 件事

**没有去重**——如果你向 SQS 发送完全相同的作业多次,它将被处理多次。这可能并不令人惊讶。如果你向任何 Laravel 队列发送完全相同的作业,你将结束处理该作业多次!

**无法保证消息顺序**——你不会一定按照发送作业的顺序来处理作业,即使你只使用一个队列工作程序。

这与其他 Laravel 队列驱动程序(如数据库和 Redis 驱动程序)不同。

请注意,标准 SQS 会 *尝试* 按接收作业的顺序发送作业,但由于 SQS 的规模和架构,这并不总是可能的。这一点在 SQS 常见问题解答中说明

FIFO SQS

FIFO 队列具有 2 种保证

  1. Exactly-Once 处理
  2. 消息顺序

FIFO 队列会删除重复作业。你可以允许 SQS 根据作业数据来确定作业是否重复,或者你可以将 Deduplication ID 设置为你选择的任何值。SQS 使用该值来与其他作业进行比较。如果它发现一个具有相同内容或 Deduplication ID 的作业,它将删除重复的作业。

因此,这有助于你确保不会处理同一个作业多次。

FIFO 还保证消息顺序。FIFO 队列按发送作业的顺序传递作业(先进先出——最旧的作业/消息最先被处理)。

在前面的作业完成(删除)之前,不会发送任何作业进行处理。然而,这意味着使用多个队列工作程序是无用的。那么,如何扩展我们的 FIFO 队列以一次处理多个作业呢?

你可以使用 消息组。顺序仅在消息组内保证,因此你可以通过为应按顺序处理的作业分配唯一的消息组来在 FIFO 队列中获得并发性。

例如,您可能希望在应用程序中为每个用户分配一个消息组,在这种情况下,您的消息组 ID 可能设置为类似于“user-x”的内容,其中x 是用户 ID。

FIFO 队列还有更多内容。要了解更多信息,请参阅我们关于使用 FIFO 队列的文章!

Chris Fidao photo

CloudCastsServers for Hackers教授编码和服务器。 Chipper CI的联合创始人。

Cube

Laravel 新闻

加入 40,000 多名其他开发者,绝不错过新的提示、教程等等。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动完成和对本地和生产环境的即时反馈进行调试。

Tinkerwell
No Compromises logo

不妥协

Joel 和 Aaron 是来自 No Compromises 播客的两位经验丰富的开发人员,现在可以为您的 Laravel 项目聘用。 ⬧ 固定费率为每月 7500 美元。 ⬧ 没有冗长的销售流程。 ⬧ 没有合同。 ⬧ 100%退款保证。

不妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,以确保您的 Web 应用程序成功。

Kirschbaum
Shift logo

Shift

运行旧版本的 Laravel?即时、自动化的 Laravel 升级和代码现代化,以保持您的应用程序更新。

Shift
Bacancy logo

Bacancy

使用经验丰富的 Laravel 开发人员为您的项目增值,该开发人员拥有 4-6 年的经验,每月仅需 2500 美元。获得 160 小时的专职专业知识和 15 天的无风险试用。立即安排电话!

Bacancy
Lucky Media logo

Lucky Media

立即获得 Lucky - Laravel 开发的理想选择,拥有超过十年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel 电子商务

Laravel 的电子商务。一个开源软件包,将现代无头电子商务功能的强大功能带入 Laravel。

Lunar: Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 工作板

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动工具包

SaaSykit 是一个 Laravel SaaS 启动工具包,包含运行现代 SaaS 所需的所有功能。付款、精美结账、管理面板、用户仪表板、身份验证、就绪组件、统计信息、博客、文档等等。

SaaSykit:Laravel SaaS 启动工具包
Rector logo

Rector

您无缝升级 Laravel、降低成本和加速创新的合作伙伴,为成功公司提供服务。

Rector
MongoDB logo

MongoDB

通过强大的 MongoDB 和 Laravel 集成来增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。支持事务性、搜索、分析和移动用例,同时使用熟悉的 Eloquent API。了解 MongoDB 的灵活、现代数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的无依赖输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel 提示构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包在 Laravel 应用程序中添加评论

阅读文章