Horizon不是开箱即用工具,必须配置Redis连接(QUEUE_CONNECTION=redis)、运行php artisan horizon:install生成配置、在config/horizon.php中正确定义environments和supervisor策略,并授权生产环境访问权限,否则仪表盘打不开、队列不消费、告警不触发。

Horizon 不是“装了就能用”的开箱即用工具,它需要明确配置 Redis 连接、工作进程策略和访问权限,否则仪表盘打不开、队列不消费、告警不触发都是常态。
确认 QUEUE_CONNECTION=redis 且 Redis 可连通
Horizon 本质是 Redis 队列的可视化层,如果底层队列没走 Redis,Horizon 就是空壳。检查 .env 中必须有 QUEUE_CONNECTION=redis,不能是 sync 或 database。同时确保 REDIS_HOST、REDIS_PORT、REDIS_PASSWORD(如有)全部正确,且能从 PHP 进程直连 Redis:
- 运行
php artisan tinker后执行Redis::ping(),返回"PONG"才算通 - 若报错
Connection refused或Authentication failed,先别动 Horizon 配置,优先修复 Redis 连接 - config/database.php 中的
redis.default配置必须与环境变量一致,尤其注意database值(默认是 0,但有些部署会切到其他 DB)
运行 php artisan horizon 前必须完成 horizon:install
仅 composer require laravel/horizon 和 vendor:publish 不够,horizon:install 才会生成关键的 config/horizon.php 并注册路由。漏掉这步会导致:
- 访问
/horizon返回 404 -
php artisan horizon启动后无任何 worker 进程,日志里看不到Started watching... - config/horizon.php 中的
environments配置为空,无法定义processes或balance
正确顺序是:composer require laravel/horizon → php artisan horizon:install → php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"。
仪表盘打不开?检查 auth 权限和路由注册
默认情况下,Horizon 只允许 APP_ENV=local 环境访问 /horizon。生产环境必须显式授权,否则 403 或重定向到登录页:
- 在
AppServiceProvider@boot中添加Horizon::auth(fn ($request) => $request->user()?->email === 'admin@example.com'); - 确认
routes/web.php没有覆盖或注释掉 Horizon 的路由;新版 Horizon 通常自动注册,但若手动删过Route::get('/horizon', ...)就得补回来 - 中间件配置在
config/horizon.php的middleware数组里,不要只写auth,得包含web(否则 session 不生效)
队列不消费?重点看 supervisor 配置和 balance 策略
启动 php artisan horizon 后,控制台应输出类似 Started watching redis:default with 3 processes.。如果没有,问题大概率出在 config/horizon.php 的 environments:
-
queue字段必须写成数组,比如['default'],写成'default'会被忽略 -
balance设为'auto'时,Horizon 会动态调整进程分配,但如果所有队列都为空,它可能把进程全撤走——改回'simple'更可控 - Supervisor 配置中不能同时跑
php artisan queue:work和php artisan horizon,两者冲突,必须停掉前者 - 用
ps aux | grep horizon确认进程是否真在运行;若被 Supervisor 拉起后秒退,查storage/logs/horizon.log里的致命错误(常见于内存限制超限或配置语法错误)
最易被忽略的是:Horizon 的进程模型和传统 queue:work 不同,它依赖 Redis 的 BRPOP 阻塞监听,一旦 Redis 连接闪断或超时设置过短,worker 会静默退出而不报错。


















