Laravel 教程

在部署期间暂停所有 Laravel 队列

发布
在部署镜像期间暂停所有 Laravel 队列

There is a window during most deploys where the code on disk has changed but the workers running against it have not restarted yet. A worker that reserves a job in that window deserializes a payload written by the old code and runs it through the new code. Most of the time nothing happens. Occasionally a renamed job class or a changed constructor signature turns it into a failed job you have to replay by hand.

The usual workaround is maintenance mode, which stops far more than the queue, or queue:restart , which is a request rather than a guarantee since a worker only sees it between jobs. Laravel 13.25 adds a third option: a switch that stops every worker on every connection from reserving new work, without touching HTTP traffic.

The Command

php 工匠 队列:暂停 - 全部

And to undo it:

php 工匠 queue:resume - 全部

The queue argument on both commands is now optional, so --all is the only thing you pass. Without the flag they behave as before and take a connection:queue pair.

The same switch is on the Queue facade for deploy scripts written in PHP, or for a controller behind an admin panel:

使用 Illuminate\Support\Facades\Queue ;
队列 :: pauseAll ();
// ...
队列 :: resumeAll ();

What Pausing Actually Does

A paused queue stops workers from reserving new jobs. The worker process stays alive and keeps looping, it just sleeps instead of popping. A job already being processed when you pause runs to completion, so a queue:pause --all in a deploy script does not interrupt anything mid-flight. Producers are unaffected too: SomeJob::dispatch() keeps writing to Redis or the database, and those jobs sit there until you resume.

Mechanically it is one cache key, illuminate:queues:paused , written with forever() . Workers already read the cache once per loop to check for restart and per-queue pause signals, and the global key is fetched in the same many() call, so this adds no extra round trips. QueueManager::isPaused()getPausedQueues() both report a queue as paused when either the global key or its own key is set.

The Two Switches Are Independent

pause()pauseAll() write different keys, and they are deliberately not aware of each other. If a queue was paused individually, resumeAll() leaves it paused:

队列 :: 暂停 'redis' , “进口” (英文): // parked while we investigate a bad job
队列 :: pauseAll (); // deploy starts
队列 :: resumeAll (); // deploy finishes
队列 :: isPaused 'redis' , “进口” (英文): // 真的

This is the behavior you want in a deploy script. Somebody parked the imports queue on purpose an hour ago, and a deploy running resumeAll() should not quietly undo that. Clearing an individual pause still takes queue:resume redis:imports

活动

Two events fire alongside the existing per-queue QueuePausedQueueResumed :

使用 Illuminate\Queue\Events\QueuesPaused ;
使用 Illuminate\Queue\Events\QueuesResumed ;
事件 :: 功能 QueuesPaused $event) {
日志 :: 警告 'All queues paused' (英文):
});

进一步阅读

保罗·雷德蒙德照片

Laravel News 特约撰稿人。全栈 Web 开发人员兼作家。

赞助

acquaintsoft 标志
了解软科技

以每小时 20 美元的价格聘请具备人工智能专业知识的 Laravel 开发人员。48 小时内即可开始工作。

访问 Acquaint Softtech
组合:多列上的精妙关系图

组合:多列上的精妙关系

阅读文章
MKSine:一款基于 Filament 的 CMS,支持插件、主题和模块(图片)

MKSine:一款基于 Filament 的内容管理系统,支持插件、主题和模块

阅读文章
在 Inertia.js v3.7 图片中取消飞行中表单提交

在 Inertia.js v3.7 中取消飞行中表单提交

阅读文章
Laravel Starter Kits 现在附带 Vite+ 图片

Laravel Starter Kits 现在随附 Vite+

阅读文章
Laravel Eloquent 中使用 refreshForUpdate() 实现悲观锁定 图片

Laravel Eloquent 中使用 refreshForUpdate() 实现悲观锁定

阅读文章
Laravel 异常消息中的掩码查询绑定图片

Laravel 异常消息中的查询绑定掩码

阅读文章