Laravel Horizon任务处理延迟:如何让待处理任务立即执行?
解决Laravel Horizon任务延迟执行的问题
针对你遇到的Horizon处理任务延迟、但php artisan queue:work正常的情况,可按以下步骤排查解决:
1. 调整Horizon Worker的休眠间隔
Horizon的Worker默认在无任务时会休眠一段时间,若此值设置过大,会导致新任务无法被及时拾取。修改config/horizon.php中对应环境的Worker配置:
'production' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default'], 'balance' => 'auto', 'processes' => 10, 'tries' => 3, 'sleep' => 1, // 将默认的60秒改为1秒,缩短轮询间隔 'timeout' => 60, ], ],
修改后需重启Horizon使配置生效:
php artisan horizon:terminate php artisan horizon
2. 关闭自动进程平衡(按需)
若使用balance: auto策略,Horizon会根据队列长度动态调整Worker进程数,可能导致进程扩容延迟。可尝试关闭自动平衡,固定Worker进程数:
'supervisor-1' => [ // ... 其他配置 'balance' => false, 'processes' => 5, // 固定进程数,根据业务需求调整 'min_processes' => 5, 'max_processes' => 10, ],
3. 清除Horizon缓存并重启进程
配置修改后若未生效,可能是缓存导致。执行以下命令清除缓存并重启Horizon:
php artisan horizon:clear php artisan horizon:terminate php artisan horizon
4. 验证Redis Pub/Sub机制
Horizon依赖Redis的发布订阅(Pub/Sub)来通知Worker有新任务,若此机制异常,Worker只能通过轮询获取任务。可通过redis-cli测试:
# 终端1:订阅Horizon的任务通知频道 redis-cli SUBSCRIBE laravel_database_queue_notifications # 终端2:发布测试消息 redis-cli PUBLISH laravel_database_queue_notifications "test"
若终端1未收到消息,需检查Redis配置是否禁用了Pub/Sub,或服务器防火墙是否限制了Redis端口。
5. 确认队列监听配置
确保Horizon的Worker监听了任务分发的所有队列。若任务被分发到多个队列,需在queue数组中列出所有队列:
'supervisor-1' => [ // ... 其他配置 'queue' => ['default', 'high'], // 包含所有业务用到的队列 ],
内容的提问来源于stack exchange,提问作者MKN
相关产品推荐
相关产品推荐

