Node.js服务器意外Clean Exit问题排查与自动重启方案咨询
一、先排查意外退出的原因
[nodemon] clean exit表示进程以状态码0主动退出,属于正常退出逻辑,但不是预期行为,从这些方向定位问题:
补全Promise错误捕获
你的startServer是异步函数,但调用时未添加catch逻辑。如果内部异步操作(比如loaders里的数据库连接、配置加载)出现未处理的Promise拒绝,可能触发进程静默退出。给启动代码补全错误捕获:startServer().catch(err => { Logger.error('服务器启动失败:', err); process.exit(1); });监听进程退出相关事件
在代码中添加事件监听,输出退出细节,方便定位:// 记录进程退出状态码 process.on('exit', code => { Logger.info(`进程退出,状态码: ${code}`); }); // 捕获未处理的Promise拒绝 process.on('unhandledRejection', (reason, promise) => { Logger.error('未处理的Promise拒绝:', reason); Logger.error('关联Promise:', promise); }); // 捕获未捕获的同步异常 process.on('uncaughtException', err => { Logger.error('未捕获的异常:', err); process.exit(1); }); // 记录系统发送的终止信号 process.on('SIGTERM', () => Logger.info('收到SIGTERM信号,准备退出')); process.on('SIGINT', () => Logger.info('收到SIGINT信号,准备退出'));开启nodemon详细日志
修改package.json的启动脚本,启用verbose模式查看更多细节:"start": "nodemon -v"如果在Docker或共享目录下运行,再加
-L启用轮询监听文件变化:"start": "nodemon -v -L"排查外部依赖或资源问题
比如数据库连接断开后未正确重连、第三方服务调用出错导致进程逻辑终止、内存泄漏被系统kill(系统kill一般不会是clean exit,但仍需排查)。可以检查日志中的内存使用情况,或排查loaders模块里的异步操作是否存在未处理的错误分支。
二、实现服务器意外退出后自动重启
nodemon默认仅在进程崩溃(非0状态码)时自动重启,clean exit场景下会等待文件变化才重启,通过以下方式修改行为:
配置nodemon的exitcrash选项
直接修改启动脚本:"start": "nodemon --exitcrash"或新建
nodemon.json配置文件,配置更清晰:{ "exitcrash": true, "watch": ["src/**/*.ts"], "exec": "ts-node src/app.ts" }配置后,无论进程是正常退出还是崩溃,nodemon都会自动重启。
兜底方案:用pm2管理进程
如果nodemon配置未生效,可换用pm2。pm2默认会自动重启所有意外退出的进程,包括clean exit场景。
先安装pm2:npm install pm2 -g
创建ecosystem.config.js配置文件:module.exports = { apps: [{ name: 'your-server', script: 'ts-node', args: 'src/app.ts', watch: ['src'], autorestart: true, restart_delay: 1000, log_date_format: 'YYYY-MM-DD HH:mm:ss' }] };启动命令:
pm2 start ecosystem.config.js
三、额外的代码检查点
- 检查HTTPS配置中的key文件:你代码里key文件后缀是
.crt,私钥文件一般后缀为.key,确认文件名是否有误,避免场景化错误触发退出。 - 添加TLS错误监听:防止客户端TLS握手错误导致进程异常:
httpsServer.on('tlsClientError', (err, socket) => { Logger.error('TLS客户端错误:', err); socket.destroy(err); });
内容的提问来源于stack exchange,提问作者Rustam Ansari

