Laravel如何停止或重启指定队列对应的worker进程?
Laravel 原生的 queue:restart 命令默认不支持按队列筛选停止worker,你可以通过以下两种方案实现需求:
方案1:自定义支持队列筛选的重启命令(适配所有worker部署方式)
实现逻辑
原生queue:restart的原理是在缓存中写入全局重启时间戳,所有worker每次处理任务前都会对比自身启动时间,若早于重启时间戳则自动退出。我们在此基础上新增按队列名隔离的重启时间戳校验,不影响原有全局重启功能。
实现步骤
- 生成自定义Artisan命令
执行以下命令生成命令类:php artisan make:command QueueRestartByQueueCommand - 编写命令业务逻辑
打开生成的app/Console/Commands/QueueRestartByQueueCommand.php文件,替换内容如下:<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\Cache; class QueueRestartByQueueCommand extends Command { protected $signature = 'queue:restart {--queue= : 指定要重启的队列名称,不传则执行全局重启}'; protected $description = '重启所有worker,或仅重启指定队列的worker'; public function handle() { $queue = $this->option('queue'); if ($queue) { Cache::forever("queue:restart:{$queue}", now()->getTimestamp()); $this->info("指定队列[{$queue}]的重启标记已下发,worker处理完当前任务后将自动退出"); } else { // 不传queue参数时走原生全局重启逻辑 Cache::forever('illuminate:queue:restart', now()->getTimestamp()); $this->info('全局重启标记已下发,所有worker处理完当前任务后将自动退出'); } } } - 新增worker启动事件监听
打开app/Providers/AppServiceProvider.php,在boot方法中添加如下逻辑,让worker支持校验对应队列的重启标记:use Illuminate\Queue\Events\WorkerStarting; use Illuminate\Support\Facades\Cache; public function boot() { // 原有其他boot逻辑保留 event()->listen(WorkerStarting::class, function (WorkerStarting $event) { // 先保留原生全局重启校验 $globalRestartTs = Cache::get('illuminate:queue:restart'); if ($globalRestartTs && $event->worker->getStartedAt() < $globalRestartTs) { exit(0); } // 新增指定队列重启校验 $workerQueues = explode(',', $event->options->queue); foreach ($workerQueues as $queue) { $queueRestartTs = Cache::get("queue:restart:{$queue}"); if ($queueRestartTs && $event->worker->getStartedAt() < $queueRestartTs) { exit(0); } } }); }
配置完成后你就可以直接使用需求中的命令,仅停止指定队列的所有worker:
php artisan queue:restart --queue=my_queue
注意:和原生restart行为一致,命令下发后worker不会立即停止,会等当前正在执行的任务处理完成后再退出。
方案2:基于Supervisor快速操作(仅适配Supervisor部署worker的场景)
如果你使用Supervisor管理队列worker,且不同队列的worker配置了独立的进程组,可直接通过Supervisor命令操作对应队列的所有进程,无需修改业务代码:
- 停止指定队列的所有worker:
supervisorctl stop 你的队列对应进程组名:* - 重启指定队列的所有worker:
supervisorctl restart 你的队列对应进程组名:*
示例:如果你在Supervisor中配置my_queue队列的进程组名为
[program:laravel-worker-my_queue],则对应命令为supervisorctl stop laravel-worker-my_queue:*
内容的提问来源于stack exchange,提问作者ttvd94
相关产品推荐
相关产品推荐

