使用PM2搭配Node.js 14+时Sails.js文件上传卡顿求助
文件上传停滞排查与解决方案
问题现象
- 文件上传启动后,触发2-3次
progress事件就停滞挂起 - 仅写入磁盘约20%内容(示例:124KB文件仅上传64KB)
触发与正常场景
触发场景
- 使用PM2启动应用,且Node.js版本为14/16/18/20时
正常场景
- 不使用PM2启动应用
- PM2搭配Node.js v12启动
- 上传3KB左右的极小文件时
已尝试方案
- 替换存储适配器:从
skipper-s3改为skipper本地存储,问题依旧,排除存储端问题 - 跳过
skipper直接上传至AWS,问题仍存在 - 尝试调整body parser配置,但无明确方向
- 在上传代码后添加
await sleep(3000)延迟,未解决 - 升级PM2从4.5版本至5.3.0,问题仍存在
卡顿代码片段
console.log("There is at least one file to upload, start upload"); req.file('attachment').upload({ // 限制总上传大小不超过约10MB maxBytes: 10000000, onProgress: function (o) { console.log("progess ", o.written); } }, function whenDone(err, uploadedFiles) { console.log("upload completed"); // 永远无法执行到此处 console.log(err); if (err) { return res.serverError(err); } }); // const sleep = ms => new Promise(r => setTimeout(r, ms)); // await sleep(3000);// 等待3秒再重试 console.log("AFTER FILE upload");
日志输出
There is at least one file to upload, start upload AFTER FILE upload progess 22770 progess 22771 progess 48962 progess 65372
排查方向与解决方案
- 禁用PM2集群模式:Node.js 14+对stream处理逻辑有调整,PM2默认的cluster模式可能导致请求流被跨进程分发中断。尝试用
pm2 start app.js --no-cluster启动应用,强制单进程运行验证。 - 调高文件描述符限制:Node.js 14+对文件描述符使用更严格,PM2进程可能因描述符耗尽导致写入停滞。执行
ulimit -n 65535临时调高限制,重启PM2测试。 - 调整流缓冲参数:检查skipper或body parser的缓冲配置,显式设置更大的
highWaterMark,比如在upload配置中添加highWaterMark: 64 * 1024(64KB),适配中等文件的流处理需求。 - 关闭PM2实时日志收集:PM2的stdout日志收集可能在高流量时阻塞进程,导致上传流停滞。尝试用
pm2 start app.js --no-log启动,避免日志阻塞。 - 禁用Node.js实验性流特性:Node.js 14+部分实验性特性可能与上传流冲突,启动PM2时添加
--node-args="--no-experimental-fetch"参数,禁用可能影响流的特性。
内容的提问来源于stack exchange,提问作者0xMrZK
相关产品推荐
相关产品推荐

