Node.js服务端渲染出现Unknown system error -116错误求助
解析Node.js服务端渲染中出现的Unknown system error -116问题
先梳理下你的运行环境:
- React JS v16.8.6
- Node JS v8.14.0
- 宿主系统:Ubuntu v16.04
- 架构:服务端渲染(SSR),通过PM2管理进程
你提供的错误日志详情如下:
{ "Error": "Unknown system error -116: Unknown system error -116, write", "errno": -116, "code": "Unknown system error -116", "syscall": "write", "level": "error", "message": "uncaughtException: Unknown system error -116: Unknown system error -116, write\nError: Unknown system error -116: Unknown system error -116, write", "stack": "Error: Unknown system error -116: Unknown system error -116, write", "exception": true, "date": "Sat Jun 29 2019 19:52:25 GMT+0530 (IST)", "process": { "pid": 127, "uid": 0, "gid": 0, "cwd": "/opt/maatran", "execPath": "/usr/bin/node", "version": "v8.14.0", "argv": [ "/usr/bin/node", "/usr/lib/node_modules/pm2/lib/ProcessContainer.js", "start", "ecosystem.config.js" ], "memoryUsage": { "rss": 184356864, "heapTotal": 154181632, "heapUsed": 138251728, "external": 929873 } }, "os": { "loadavg": [ 0.279296875, 0.14697265625, 0.099609375 ], "uptime": 326785 }, "trace": [], "timestamp": "2019-06-29T14:22:25.457Z" }
错误核心分析
这个错误发生在write系统调用阶段,Node.js进程尝试写入数据(可能是磁盘文件、网络响应流或者PM2日志流)时触发了系统级错误。在Ubuntu 16.04环境下,错误码116对应ETIME(定时器超时),但Node.js v8.x版本会将部分系统错误码以负数形式返回,所以这里的-116本质是写入操作超时失败。
可能的解决方案
我整理了几个排查方向,你可以按顺序尝试:
检查磁盘状态与权限
- 先确认
/opt/maatran所在磁盘是否已满:执行df -h /opt/maatran查看可用空间。如果磁盘耗尽,清理无用文件或者扩容即可。 - 虽然进程以root权限运行,但还是要确认目录写入权限:执行
ls -ld /opt/maatran,确保权限包含w(写入)位。 - 排查磁盘IO异常:查看系统日志
dmesg或/var/log/syslog,搜索是否有磁盘读写错误的提示,比如IO error类的日志。
- 先确认
排查PM2进程管理问题
- 你的进程通过PM2的ProcessContainer启动,可能是PM2日志写入环节出了问题。先尝试重启PM2进程:
pm2 restart ecosystem.config.js。 - 清理PM2积压的旧日志:执行
pm2 flush,避免因日志文件过大导致写入超时。 - 检查PM2的日志配置,确保日志文件路径正确且有足够空间,可以查看
ecosystem.config.js中的out_file和error_file配置项。
- 你的进程通过PM2的ProcessContainer启动,可能是PM2日志写入环节出了问题。先尝试重启PM2进程:
升级Node.js版本
- Node.js v8.14.0是比较老旧的版本(已停止维护),存在一些已知的系统调用错误处理bug。建议升级到v8.x分支的最新稳定版(比如v8.17.0),或者直接迁移到长期支持的v10.x/v12.x版本。注意升级前要先测试React SSR的兼容性,确保React 16.8.6在新版本下能正常运行。
优化SSR的流写入错误处理
- 在SSR场景中,如果客户端提前断开连接,Node.js写入响应流时会触发错误。你可以在代码中添加流错误监听,避免未捕获异常导致进程崩溃:
app.get('/', (req, res) => { const renderStream = renderToNodeStream(<App />); // 监听响应流错误 res.on('error', (err) => { console.error('Response stream error:', err); }); // 监听渲染流错误 renderStream.on('error', (err) => { console.error('SSR render error:', err); res.status(500).send('Server Error'); }); renderStream.pipe(res, { end: false }); renderStream.on('end', () => { res.end('</body></html>'); }); });
- 在SSR场景中,如果客户端提前断开连接,Node.js写入响应流时会触发错误。你可以在代码中添加流错误监听,避免未捕获异常导致进程崩溃:
如果以上方法都没解决问题,可以补充以下信息方便进一步排查:
- 错误是随机触发还是访问特定页面时必现?
exceptions.log中是否还有其他关联的错误日志?- 系统的IO负载情况(可以用
iostat -x 1 5查看实时IO统计)
内容的提问来源于stack exchange,提问作者Murali Manohar
相关产品推荐
相关产品推荐

