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

同一服务器上两个Laravel Horizon实例任务冲突问题求助

问题

我有一台测试服务器,运行着两个完全相同的Laravel应用版本,各自配有独立的Laravel Horizon实例(一个是新功能预发布站点stg,一个是镜像生产环境的演示站点demo)。这些应用部署在Docker容器中,共享同一个Redis数据库(即单个Redis容器,两个独立PHP容器运行Horizon)。它们已稳定运行数月,但近一周出现异常。

最初发现问题时,我意识到未为每个站点设置HORIZON_PREFIX环境变量,随后已分别配置为stg:和demo:以区分。我执行了Redis的FLUSHDB命令,并重启所有Docker容器,重启时会运行脚本重置应用缓存:

echo 'Clearing previous cache...'
(cd /var/www/html && php artisan cache:clear && php artisan config:clear && php artisan route:clear && php artisan view:clear)
echo "Caching configuration..."
(cd /var/www/html && php artisan config:cache && php artisan route:cache && php artisan view:cache)
echo "Starting Laravel application..."

但设置独立前缀后,提交任务时仍会同时发送到stg和demo队列。查看Redis数据库,已实现stg和demo的键分离,但问题依旧:提交到demo的任务会被两个Horizon实例接收,在stg上执行失败,在demo上则卡在待处理任务列表;关闭stg站点后,任务可在5秒内成功完成。

Redis键列表如下:

127.0.0.1:6379> KEYS *
 1) "demo:monitor:time-to-clear"
 2) "demo:measured_jobs"
 3) "stg:supervisor:7e9026e6c9b7-6nE4:supervisor-2"
 4) "demo:db636ed0-c5ac-4233-9867-aed91e9397af"
 5) "demo:masters"
 6) "stg:last_snapshot_at"
 7) "stg:monitor:time-to-clear"
 8) "demo:master:3a70f005424b-Bteh"
 9) "stg:supervisor:7e9026e6c9b7-6nE4:supervisor-0"
10) "stg:failed:App\Models\CustomList:79"
11) "demo:queue:default"
12) "stg:masters"
13) "demo:last_snapshot_at"
14) "demo:9fcc3255-cb91-4ad6-ada1-24528c806b63"
15) "demo:pending_jobs"
16) "stg:failed_jobs"
17) "stg:failed:App\Models\CustomList:48"
18) "stg:recent_failed_jobs"
19) "stg:9fcc3255-cb91-4ad6-ada1-24528c806b63"
20) "demo:supervisor:3a70f005424b-Bteh:supervisor-0"
21) "stg:supervisor:7e9026e6c9b7-6nE4:supervisor-1"
22) "demo:measured_queues"
23) "stg:master:7e9026e6c9b7-6nE4"
24) "stg:db636ed0-c5ac-4233-9867-aed91e9397af"
25) "stg:6d53039b-dcd9-41f6-af5e-3c89203dd6e7"
26) "demo:completed_jobs"
27) "demo:supervisors"
28) "demo:supervisor:3a70f005424b-Bteh:supervisor-2"
29) "stg:supervisors"
30) "demo:d96f69ba-60fd-4d2f-a8c0-1a8091cb98bf"
31) "demo:job:App\Jobs\SyncData"
32) "demo:supervisor:3a70f005424b-Bteh:supervisor-1"
33) "demo:0705c7ec-d81e-4e26-9f40-d5c045e33c5b"
34) "stg:b159e41e-fb2e-40f9-9c3e-c404deb1bacd"
35) "demo:6d53039b-dcd9-41f6-af5e-3c89203dd6e7"
36) "demo:recent_jobs"
37) "demo:b159e41e-fb2e-40f9-9c3e-c404deb1bacd"
127.0.0.1:6379> 

版本信息:

Laravel Horizon v5.16.1 
Laravel v9.52.9

请问还需执行哪些操作才能避免这种任务冲突?

解决方案
  • 确认Horizon配置文件的前缀读取逻辑:检查config/horizon.php中的prefix配置项,确保是'prefix' => env('HORIZON_PREFIX', 'horizon:'),,而非硬编码的固定值,保证环境变量能被正确读取。
  • 强制Horizon进程优雅重启:进入每个PHP容器内部,执行php artisan horizon:terminate,让Horizon完全重启加载新配置。仅重启Docker容器可能无法让Horizon进程重新读取配置。
  • 验证队列连接的前缀一致性:查看config/queue.php中Redis连接的prefix配置,确保和对应站点的HORIZON_PREFIX保持一致,避免任务投递时使用了错误的前缀。
  • 重新发布Horizon配置(若有自定义修改):执行php artisan horizon:publish,覆盖旧的配置文件,确保最新的前缀规则被应用,之后重新执行配置缓存命令。
  • 检查Redis全局前缀:确认Redis服务的redis.conf中未设置全局prefix,避免全局前缀和Horizon的前缀叠加导致队列识别混乱。
  • 清理Horizon监控数据:执行php artisan horizon:clear清除Horizon的快照、监控数据,避免旧的跨站点数据残留干扰任务调度。
  • 验证任务投递目标队列:提交测试任务后,用Redis命令确认任务仅进入对应前缀的队列(比如demo任务只在demo:queue:default中),排查是否存在任务投递逻辑错误。

内容的提问来源于stack exchange,提问作者Nathan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:05:42