为何PM2无法检测Node.js基础错误?构建异常未被识别咨询
问题结论
前两种情况是PM2默认行为导致的正常现象,但可以通过配置调整实现你“损坏构建不被标记为存活”的需求。
原因解析
PM2默认会自动重启崩溃的进程,而throw new Error("test")和import "non-existing-file.js"属于启动阶段的同步异常:Node.js执行代码时直接抛出异常,进程瞬间崩溃退出。但PM2的默认重启策略会立刻重启进程,当你执行pm2 status时,重启后的进程已经处于运行状态,因此显示为active。
而process.exit(1)是主动调用退出,PM2捕获到非0退出码后,结合默认的min_uptime(默认1000ms)判断:如果进程存活时间不足最小阈值,会标记为异常状态,不会立即重启。
解决方案
针对你的需求,推荐以下几种配置方案:
1. 限制快速重启次数与最小存活时间
通过min_uptime设置进程需要存活的最短时间,max_restarts设置一段时间内的最大重启次数。如果进程在min_uptime内崩溃,且重启次数超过max_restarts,PM2会将进程标记为errored。
创建ecosystem.config.js配置文件:
module.exports = { apps: [{ name: "your-app", script: "app.js", min_uptime: "1s", // 进程至少存活1秒才视为正常启动 max_restarts: 2, // 1分钟内最多重启2次 restart_delay: 500 // 重启间隔500ms }] };
执行pm2 start ecosystem.config.js启动应用。
2. 启用就绪信号机制
让应用主动向PM2发送就绪信号,只有收到信号后PM2才会将进程标记为active。如果启动阶段出错,应用不发送信号,PM2会判定进程启动失败。
配置文件中添加wait_ready: true:
module.exports = { apps: [{ name: "your-app", script: "app.js", wait_ready: true, listen_timeout: 3000 // 等待就绪信号的超时时间 }] };
在正常启动的应用代码末尾添加就绪信号发送:
// 以Express服务为例 const express = require('express'); const app = express(); app.listen(3000, () => { console.log('Server running'); process.send('ready'); // 发送就绪信号给PM2 });
如果构建损坏(如导入错误),代码执行到异常处直接崩溃,不会发送ready信号,PM2超时后会标记进程为errored。
3. 自定义健康检查
通过PM2的post-start钩子或外部脚本,检查应用是否真的正常运行(比如访问健康接口),如果检查失败,手动让PM2停止或标记进程异常。
示例配置添加post-start钩子:
module.exports = { apps: [{ name: "your-app", script: "app.js", post_start: "./health-check.sh" }] };
health-check.sh脚本示例:
#!/bin/bash sleep 2 curl -f http://localhost:3000/health || pm2 stop your-app
内容的提问来源于stack exchange,提问作者Jscti

