使用 SQS FIFO 队列
发布日期:作者: Chris Fidao
AWS 的简单队列服务 (SQS) 是一种出色的、高扩展性且极其廉价的方式来获得可靠的队列。
SQS 的一个小小缺陷是,您无法保证作业的处理顺序。
如果队列中有 10 个作业,您不知道队列工作者会获得哪个作业。
对于我们大多数人来说,这完全没问题。如果您需要按顺序完成某些作业,可以使用 Laravels 作业链接。
但是,这并不适用于所有情况。
例如,在 Chipper CI 中,我们需要按接收顺序处理构建。我们必须等待任何时候可能出现的传入 Webhook,因此我们不能简单地添加到作业链接中。相反,我们依靠 SQS FIFO 队列。
FIFO 队列
FIFO 代表先进先出。这意味着最旧的作业将始终是第一个被分配给队列工作者的作业。
最旧作业“后面”的作业只有在前面的作业完成之后才会被分配给队列工作者。
当您需要按顺序处理作业时,这非常有用,但这限制了扩展队列工作者的能力。
如果就这样,您永远无法使用多个队列工作者,也无法一次处理多个作业(除非创建并以某种方式管理多个 FIFO 队列)。
消息组 ID
幸运的是,FIFO 队列对此进行了考虑。事实证明,消息顺序仅在组 ID 内保证。
FIFO 队列中的每个作业(消息)都必须有一个组 ID。**任何具有相同组 ID 的作业都将按接收顺序处理**。
如果您为每个作业分配一个随机组 ID,那么由于没有共享的组 ID,将无法维护顺序。
在 Chipper CI 中,每个团队都可以有多个项目。每个项目都是一个 git 存储库,当有人将其 git 存储库更新推送到存储库时,该存储库就会被构建。
为了按顺序保持构建,我们使用 FIFO 队列,使用团队 ID 和项目 ID 创建组 ID。看起来像这样
$build = App\Build::createFromWebhook($payload); $groupId = sprintf('build-%s-%s', $build->project->team_id, $build->project_id); dispatch( (new ProcessBuild($build)) ->onMessageGroup($groupId));
SQS FIFO Laravel 软件包
为了帮助解决这个问题,我们可以使用 shiftonelabs/laravel-sqs-fifo-queue Composer 软件包。
这扩展了 SQS 队列消息类型并添加了一些功能。
最重要的是,它为我们提供了 onMessageGroup()
方法,该方法允许我们在将作业(消息)添加到 SQS FIFO 队列时添加消息组 ID。