Laravel Horizon使用Redis驱动时/tmp目录无法自动清理问题求助
解决Redis驱动搭配Horizon时/tmp目录被临时PHP文件填满的问题
环境信息
- Laravel: 5.5
- Horizon: 1.2.3
- PHP: 7.2
- Ubuntu: 16.04
- 架构: LAMP
问题现象
你遇到的这个情况确实挺棘手的,目前虽然还不能100%确定和Horizon的Redis服务器直接相关,但现象对比很明显:
- 用数据库驱动处理队列时,/tmp目录会生成
php34gs1、phpwrd42这类命名的临时PHP文件,队列处理完成后,这些文件会被自动清理,/tmp目录恢复正常; - 但切换到Redis驱动+Horizon的组合后,这些临时文件会不断累积,直到把60GB的服务器磁盘完全耗尽,现在只能靠手动CLI删除或者重启服务器来临时缓解。
直观状态对比
Redis驱动搭配Horizon时的/tmp目录状态:

数据库驱动下的/tmp目录状态:

永久留存的临时PHP文件示例:

可能的原因与解决思路
结合你的环境和现象,我整理了几个核心排查和解决方向:
1. 常驻Worker进程的临时文件回收问题
Horizon的Worker是常驻进程,而数据库驱动的Worker通常是短生命周期的(处理完一个或一批队列就退出)。PHP的临时文件默认是在脚本执行结束时自动删除的,常驻Worker不会主动退出,所以这些临时文件会一直留在/tmp目录里。
- 解决思路:在Horizon配置中给Worker设置生命周期限制,比如在
config/horizon.php里调整maxTime(单个Worker运行的最长时间)或者maxJobs(单个Worker处理的最多任务数),让Worker定期重启,触发PHP的资源回收机制,自动清理临时文件。
2. 队列任务中的临时文件未手动清理
检查你的队列任务代码,是否有使用tmpfile()、tempnam()或者涉及文件上传的逻辑?在常驻进程中,这些临时文件不会像短脚本那样自动销毁,必须在任务完成后手动调用unlink()来删除。
- 解决思路:梳理所有队列任务中的临时文件操作,确保每个临时文件在使用完毕后都被手动删除,比如用
try-finally块来保证即使任务出错也能清理文件。
3. 系统层面的临时文件清理机制失效
Ubuntu 16.04默认会通过systemd-tmpfiles或者tmpwatch来定期清理/tmp目录的旧文件,如果这个机制失效,也会导致文件累积。
- 解决思路:
- 检查
/etc/tmpfiles.d/tmp.conf的配置,确保有类似D /tmp 1777 root root 1d的规则(表示每天清理/tmp目录下的文件); - 手动执行
systemd-tmpfiles --clean来测试清理是否正常,同时确保systemd-tmpfiles-clean.timer服务是开启状态:sudo systemctl enable --now systemd-tmpfiles-clean.timer。
- 检查
4. 版本兼容性的潜在bug
你使用的Laravel 5.5和Horizon 1.2.3都是比较旧的版本,可能存在已知的临时文件泄漏bug。
- 解决思路:尝试升级Horizon到对应Laravel 5.5支持的最新版本(Horizon 1.x的最新版本是1.5.0,兼容Laravel 5.5),或者查看Laravel和Horizon的官方issue,确认是否有类似的问题被修复。
内容的提问来源于stack exchange,提问作者Yamen Ashraf
相关产品推荐
相关产品推荐

