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
QueuePaused
和
QueueResumed
:
使用
Illuminate\Queue\Events\QueuesPaused
;使用
Illuminate\Queue\Events\QueuesResumed
;事件
::
听
(
功能
(
QueuesPaused
$event) {
日志
::
警告
(
'All queues paused'
(英文):});
进一步阅读
- 在 Laravel 12 中暂停队列指定秒数
封面
pauseFor(), which is the right tool for backing off a single queue temporarily - Laravel 13.8.0 中的队列级检查方法 covers reading what is currently sitting on a queue
- Laravel Jobs and Queue 101 is the background on connections and named queues
- Laravel 13.25 中暂停所有队列并引入新的 Artisan 开发 UI 包含完整的发行说明
- The global pause switch was contributed by 杰克·贝利斯 在 #61126







