You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:57:01