laravel horizon 不是开箱即快的监控面板,而是 redis 队列的编排中枢;配错会导致 redis cpu 拉满、内存暴涨、任务重复,关键在 horizon_prefix、trim、metrics 和 dashboard.limit 等配置优化。

直接说结论:Laravel Horizon 不是“开了就快”的队列监控面板,它是 Redis 队列能力的编排中枢——用对了能扛万级任务,配错反而让 Redis CPU 拉满、页面卡死、任务重复执行。
为什么 Horizon 启动后 Redis 内存暴涨、CPU 占用飙升
Horizon 默认每秒执行大量 ZRANGE、HGETALL、LLEN 命令,尤其在未设前缀或高任务量场景下,会触发 KEYS horizon:* 类扫描操作。生产环境跑 KEYS * 几乎等于自毁。
- 必须在
.env中显式设置HORIZON_PREFIX=horizon:,否则它会扫全库 key - 检查
config/horizon.php中的'trim'值:默认['recent' => 100, 'failed' => 1000]过大,建议压到50和200 -
'metrics' => ['jobs' => true, 'requests' => false, 'redis' => false]—— 关掉requests和redis两项,它们是资源消耗主力
Horizon 和 queue:work 能不能共存
不能。两者同时运行会导致同一任务被多个进程争抢消费,出现重复执行、状态错乱、失败日志污染等问题。
- 启动 Horizon 前,必须先清理残留:
php artisan horizon:terminate - 用
ps aux | grep queue:work确认所有queue:work进程已退出 - Supervisor 配置中只保留一个
program段,command 设为php artisan horizon,删掉所有laravel-worker相关段 - 并发数统一由
config/horizon.php的environments块控制,比如'processes' => 6,无需额外配numprocs
任务列表加载慢、前端卡顿甚至 504 超时
根本原因是 Horizon Web 接口 /horizon/api/jobs/recent 默认拉取全量 recent_jobs,单日超 5 万任务时,Redis 查询和 PHP 序列化开销剧增。
- 把
config/horizon.php中的'dashboard' => ['limit' => 50]改为20~50,别留默认的100 - 禁用右上角 “Auto-refresh”,改手动点 “Refresh” —— 持续轮询会拖垮 Redis 连接池
- 失败页慎用 “Retry All”,它会瞬间向 Redis 写入大量新 job;应优先用
php artisan queue:retry [id]单条重试 - 如需查历史,直接查数据库
failed_jobs表 + Laravel Telescope 补充上下文,比 Horizon 更稳
Redis 驱动选型与并发吞吐的真实瓶颈
Redis 队列本身不是性能瓶颈,真正卡住的是 Horizon 的指标采集 + Dashboard 渲染逻辑。原生 queue:work 在 Redis 驱动下并发跑 8–12 个进程,吞吐常高于开 Horizon 的单主进程模式。
- 高吞吐纯消费场景(如日志归档、邮件批量发送),用 Supervisor 管理多
queue:work更轻量、更可控 - 需要弹性扩缩容、故障自愈、延迟队列、优先级调度等高级能力,才值得上 Horizon
- 若用 Horizon,务必搭配
redis-cli --bigkeys定期检查 key 分布,避免单个horizon:recentzset 膨胀到百万级 - 别忽略
retry_after和timeout的匹配:Redis 驱动要求retry_after必须大于任务最大执行时间,否则任务会被重复投递
Horizon 的价值不在“看得全”,而在“控得准”。trim、metrics、limit 这三个配置项,才是决定它到底是助力还是拖累的关键开关。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











