Node.js应用中SIGTERM信号未被处理器拦截的问题排查
问题分析与解决方案
核心结论:你的钩子其实已经触发了
看控制台输出里的第一行SIGTERM signal received.,说明你写的shutdown钩子正常执行了。后面的npm ERR! code ELIFECYCLE和错误码143不是真的错误,只是npm检测到子进程被SIGTERM终止后给出的提示信息——进程因信号终止时,npm会默认返回这个状态码。
为什么你会觉得钩子没触发?
大概率是信号发送的目标PID错误:
- 用
npm start启动服务时,系统会生成三层进程链:npm→nodemon→ 你的Node.js应用进程 - 如果你把SIGTERM发给了
npm或nodemon进程,信号转发逻辑可能不稳定:nodemon默认收到SIGTERM会重启应用而非转发,npm转发信号的时机也可能导致你误以为钩子没执行 - 正确的目标应该是你的Node.js应用的实际运行PID(对应
dist/index.js的进程)
解决步骤
定位正确的PID
执行命令:ps aux | grep node在输出里找到对应
dist/index.js的进程PID,排除nodemon和npm的进程。配置nodemon转发终止信号(可选)
如果你希望通过nodemon转发SIGTERM到应用,修改启动命令或nodemon配置:- 修改
package.json的启动脚本:"start": "nodemon --signal SIGTERM dist/index.js" - 或者创建
nodemon.json配置文件:{ "signal": "SIGTERM" }
这样nodemon收到SIGTERM时,会把信号传递给你的Node应用,确保钩子触发。
- 修改
优化钩子的退出逻辑(可选)
为了避免npm抛出ELIFECYCLE提示,可以在钩子中手动以正常状态码退出:process.on('SIGTERM', () => { console.log('SIGTERM signal received.'); // 这里添加清理数据库连接、关闭文件句柄等优雅退出逻辑 process.exit(0); });
内容的提问来源于stack exchange,提问作者Ihor M.
相关产品推荐
相关产品推荐

