Laravel多优先级队列可通过四种方式实现:一、Supervisor多进程隔离监听;二、单进程多队列轮询加权重;三、Redis ZSET自定义优先级驱动;四、OpenResty动态路由至专用Worker容器。

如果您在Laravel应用中需要处理不同紧急程度的任务,例如邮件发送、日志归档和实时通知,而Docker环境中仅运行单一队列监听器,则无法区分任务执行顺序。以下是实现多优先级队列服务的多种部署方法:
一、使用多个Supervisor进程分别监听不同队列
通过Supervisor管理多个artisan queue:work进程,每个进程绑定独立队列名与优先级参数,实现物理隔离的并发监听。
1、在Docker容器内的supervisord.conf中添加三个program段,分别对应high、default、low队列。
2、为high队列配置command = php /var/www/artisan queue:work --queue=high --sleep=3 --max-jobs=1000 --tries=3。
3、为default队列配置command = php /var/www/artisan queue:work --queue=default --sleep=5 --max-jobs=500 --tries=2。
4、为low队列配置command = php /var/www/artisan queue:work --queue=low --sleep=10 --max-jobs=100 --tries=1。
5、确保每个program的process_name以%(program_name)s_%(process_num)02d格式命名,避免冲突。
6、重启supervisord服务使配置生效:supervisorctl reread && supervisorctl update && supervisorctl start all。
二、单进程多队列轮询并设置权重调度
利用Laravel原生支持的多队列轮询机制,在一个queue:work进程中按指定顺序和频率消费多个队列,通过--queue参数控制优先级权重。
1、修改Dockerfile中CMD指令为:CMD ["php", "artisan", "queue:work", "--queue=high,default,low", "--sleep=3"]。
2、将high队列置于参数列表首位,确保其被优先扫描;default次之;low最后。
3、调整--sleep值为较小数值(如3),提升high队列响应灵敏度。
4、在.env中设置QUEUE_CONNECTION=database或redis,确保后端驱动支持原子性pop操作。
5、验证队列分发逻辑:调用dispatch((new SendEmailJob())->onQueue('high'))确认任务进入正确队列。
三、基于Redis优先级Sorted Set自定义队列驱动
绕过默认队列驱动,使用Redis的ZSET结构存储任务并按score排序,实现毫秒级优先级判定与取出。
1、在app/Providers/AppServiceProvider.php的boot方法中注册自定义驱动:Queue::extend('priority', function ($app) { return new PriorityQueue($app['redis']); });。
2、创建PriorityQueue类,实现push、pop、size等方法,使用ZADD命令插入任务并以优先级数值为score。
3、在Docker Compose中确保redis服务启用持久化与键空间通知:notify-keyspace-events Ex。
4、构建镜像时在config/queue.php中新增connections.priority配置项,指定queue名称前缀为priority_。
5、启动容器后执行php artisan queue:work priority --queue=notifications启动监听。
四、Nginx+Lua动态路由至不同队列Worker容器
借助OpenResty在反向代理层解析请求头X-Priority字段,将HTTP触发的任务分发至对应优先级的专用Worker集群。
1、部署三个独立Docker服务:worker-high、worker-default、worker-low,各自运行单一队列监听器。
2、在OpenResty的nginx.conf中添加location /api/job块,使用access_by_lua_block读取header["X-Priority"]。
3、根据header值设置upstream变量为worker-high或worker-default或worker-low对应的service名称。
4、在Laravel控制器中发送请求时添加头信息:Http::withHeaders(['X-Priority' => 'high'])->post('/api/job', $data)。
5、确保Docker网络模式为bridge且所有服务处于同一自定义网络,支持service名DNS解析。


















