Node.js通过PM2实现优雅关闭遇问题求助
解决PM2管理Node.js应用的优雅关闭问题
我之前也碰到过一模一样的问题——PM2默认会把SIGINT触发的进程退出当成「意外崩溃」,所以自动重启了。结合你的场景,咱们从配置和代码两方面调整就能搞定:
1. 用PM2配置文件明确停止规则
直接在启动命令里加参数容易遗漏,推荐用ecosystem.config.js配置文件管理,规则更清晰持久:
module.exports = { apps: [{ name: "ProcessName", script: "./server.js", silent: true, // 给应用留足优雅关闭的时间 kill_timeout: 3000, // 指定PM2停止时发送的信号为SIGINT stop_signal: "SIGINT", // 可选:让PM2等待应用发送ready信号后再标记启动完成,避免过早发停止信号 wait_ready: true, listen_timeout: 5000 }] };
之后用pm2 start ecosystem.config.js启动应用,替代原来的启动命令。
2. 完善应用的优雅关闭逻辑
你的代码已有基础,可以整合信号监听和PM2的message监听,同时要确保服务器关闭逻辑正确(比如Express用server.close()而非server.end(),后者是针对HTTP响应的):
// 以Express为例,先保存HTTP服务器实例 const express = require('express'); const app = express(); const server = app.listen(3000, () => { console.log('Server running on port 3000'); // 如果启用了wait_ready,给PM2发送ready信号 if (process.send) { process.send('ready'); } }); // 统一的优雅关闭函数 const gracefulShutdown = async () => { try { console.log('Starting graceful shutdown...'); // 关闭服务器,停止接受新连接,等待现有连接处理完成 await new Promise((resolve, reject) => { server.close((err) => { if (err) reject(err); else resolve(); }); }); // 这里可以加额外清理操作:关闭数据库连接、删除临时文件等 console.log('Server closed successfully, exiting process'); process.exit(0); } catch (err) { console.error('Error during graceful shutdown:', err); process.exit(1); } }; // 监听PM2发送的停止信号和系统信号 process.on('SIGINT', gracefulShutdown); process.on('SIGTERM', gracefulShutdown); // 监听PM2的shutdown消息 process.on('message', (msg) => { if (msg === 'shutdown') { gracefulShutdown(); } });
3. 使用正确的停止命令
别再用pm2 sendSignal SIGINT ProcessName了——这个命令只是给进程发信号,但PM2会判定进程是意外退出,进而触发重启。正确操作是用:
pm2 stop ProcessName
此时PM2会按照配置的stop_signal发送信号,然后等待kill_timeout时长,若进程仍未退出才会强制杀死,且不会重启。
验证效果
执行pm2 stop ProcessName后,通过pm2 logs ProcessName查看日志,如果能看到「Starting graceful shutdown...」和「Server closed successfully」的输出,且进程状态变为stopped,就说明优雅关闭生效了。
内容的提问来源于stack exchange,提问作者Fede E.
相关产品推荐
相关产品推荐

