当task投递数据超8KB时,Swoole自动写入系统临时文件(如/tmp/swoole_task_*.tmp)中转,文件名含随机字符串且不会自动清理,长期积累可能导致磁盘空间耗尽;需配置定时清理或改用task_ipc_mode=2/3规避。

task投递数据超过8KB会写临时文件
当使用 $server->task() 投递的数据序列化后体积 > 8KB,Swoole 默认的 task-ipc-mode=1(Unix Socket)会自动 fallback 到临时文件中转:先将数据写入磁盘临时文件,再由 Task Worker 进程读取并 unlink。这不是 bug,而是 IPC 层的保底机制。
关键点在于:这个临时文件路径由 Swoole 内部生成(通常在 /tmp 或系统临时目录下),文件名含随机字符串,且不会被自动清理——哪怕 Task 已成功执行、进程已重启,只要没被显式 unlink 或系统清理策略覆盖,它就一直残留。
- 现象:
df -h显示磁盘空间缓慢上涨,find /tmp -name "swoole_task_*.tmp" -mmin -60可查到大量新生临时文件 - 触发条件:单次
task()传入的数组/字符串序列化后 > 8192 字节 - 影响范围:仅在
task-ipc-mode=1(默认)下发生;若设为2(消息队列)或3(争抢模式消息队列),则不走临时文件,但需系统支持 msgget
gzip压缩不是万能解,要配合序列化控制
单纯对数据调用 gzencode() 后再 task() 投递,可能仍触发临时文件——因为压缩后若仍超 8KB,逻辑不变。更稳妥的做法是:先序列化 + 压缩,再判断长度,超限则拆分或拒绝。
示例逻辑:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
if (strlen(gzencode(serialize($data))) > 8000) {
// 记录告警或降级处理,比如丢弃、切片、改走 Redis 队列
throw new RuntimeException('Task payload too large after gzip');
}
- 注意:PHP 的
serialize()本身有开销,JSON 编码(json_encode())通常更紧凑,但丢失 PHP 特有类型(如 resource、Closure) - gzip 压缩率取决于数据重复度,纯随机二进制或已压缩内容(如图片 base64)几乎不减小体积
- 不要在 Task Worker 里做
gzdecode(serialize()),应在 onTask 回调开头统一解压反序列化
临时文件残留和磁盘爆满的真实风险点
最危险的不是单个大任务,而是高频小任务叠加后产生的“文件碎片”:每个任务生成一个临时文件,而 Swoole 不保证立即 unlink ——尤其当 Task Worker 异常退出、或 onTask 中抛出未捕获异常时,临时文件会彻底滞留。
- 排查命令:
lsof +L1 | grep swoole查看是否还有被打开但已删除的临时文件句柄(说明进程没 clean up) - 生产环境必须配定时清理:
find /tmp -name "swoole_task_*.tmp" -mmin +30 -delete(30分钟未访问即删) - 根本规避方式:把
task-ipc-mode改为2或3,前提是确认系统msgmax足够(cat /proc/sys/kernel/msgmax,建议 ≥ 64K)且无 SELinux 限制
为什么不能靠重启 Swoole 清理这些临时文件
因为临时文件是通过 mkstemp() 创建后直接 write/close 的,不依赖进程生命周期。Swoole 主进程或 Task Worker 重启,只会影响内存中的 task 队列状态,对磁盘上已写入且未 unlink 的文件完全无感知。
这也是很多团队在压测后发现磁盘突然告警的根本原因:测试期间高频投递大 task,产生数百个临时文件,测试结束进程退出,但文件全留在 /tmp 下不动。
- 验证方法:启动 Swoole,投递一个超限 task,立刻
ls /tmp/swoole_task_*确认文件存在,然后 kill -9 所有 swoole 进程,再查该文件是否还在 —— 它一定还在 - 所以监控不能只看进程数或内存,必须加入
du -sh /tmp/swoole_task_*.tmp 2>/dev/null | wc -l类似指标

















