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

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目录状态:
    Redis驱动下的/tmp目录

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

  • 永久留存的临时PHP文件示例:
    永久留存的临时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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:42:52