如何重载Node.js应用且不中断当前未完成请求?
PM2重载时中断活跃请求的问题解析
问题本质
你遇到的情况并非操作错误,PM2的默认重载机制不会自动等待所有活跃请求完成,这是它的默认行为。
原因说明
默认情况下,pm2 reload 会先启动新进程,随后向旧进程发送SIGINT信号触发关闭。如果你的Node.js应用没有监听该信号并处理请求收尾逻辑,旧进程会直接退出,导致未完成的请求被中断——就像你测试的10秒await接口,进程退出后无法返回响应,客户端自然会收到“无返回内容”的错误。
解决方法
要让PM2等待活跃请求完成后再关闭旧进程,需要两步配置:
- 在应用中监听
SIGINT信号,收到信号后停止接收新请求,等待现有请求处理完毕再退出。以Express框架为例:const express = require('express'); const app = express(); let server; app.get('/long-task', async (req, res) => { await new Promise(resolve => setTimeout(resolve, 10000)); res.send('任务完成'); }); server = app.listen(3000); process.on('SIGINT', async () => { // 停止接收新请求 server.close(() => { // 可在此添加资源清理逻辑,比如关闭数据库连接 console.log('所有请求处理完成,进程退出'); process.exit(0); }); }); - 配置PM2的
kill_timeout参数,给旧进程预留足够的处理时间。在ecosystem.config.js中添加:
之后使用module.exports = { apps: [{ name: 'your-app', script: 'app.js', kill_timeout: 15000 // 设置为比最长请求时间稍长的数值,单位毫秒 }] };pm2 reload ecosystem.config.js执行重载,PM2会等待配置的超时时间后再强制终止旧进程。
额外提示
- 若使用Koa等其他Node.js框架,核心逻辑一致:监听信号、关闭服务器实例、等待请求完成。
- 生产环境中务必测试该流程,确保数据库连接等资源能被正确清理,避免连接泄漏。
内容的提问来源于stack exchange,提问作者Márcio Valim
相关产品推荐
相关产品推荐

