使用NestJS+PM2实现无中断服务遇构建停滞问题求助
解决NestJS + PM2无中断服务部署问题
问题根源
- 你的
watch: '.'会让PM2监控当前目录所有文件变更,git pull和yarn build时的文件操作(比如rimraf dist删除旧构建、生成新dist)都会触发PM2重启,但此时构建可能未完成,导致找不到dist/main.js,服务中断。 prebuild阶段删除dist的操作会被PM2即时捕捉,直接触发重启,此时新dist还未生成,必然报错。
方案1:关闭自动watch,改用手动重载(推荐)
自动watch整个目录过于灵敏,容易误触发。改用拉取代码→构建→手动重载的流程,确保新代码构建完成后再替换旧服务,实现无中断更新。
1. 修改ecosystem.config.js
关闭自动watch,避免不必要的重启触发:
// ecosystem.config.js module.exports = { apps: [{ name: 'my_api', script: 'dist/main.js', watch: false, // 关闭自动监控 instances: 2, exec_mode: 'cluster', wait_ready: true, listen_timeout: 20000, kill_timeout: 5000 }] };
2. 标准部署流程
执行以下命令完成无中断更新:
- 拉取最新代码:
git pull origin master - 构建新代码:
yarn build(此时PM2不会因文件变化重启) - 平滑重载服务:
pm2 reload my_api
PM2的reload命令在集群模式下会逐个重启实例:先启动新实例并等待其就绪,再关闭旧实例,全程保证服务可用。
方案2:优化watch规则(可选)
如果需要保留自动watch功能,需限制监控范围,排除构建相关目录,避免build过程触发重启:
// ecosystem.config.js module.exports = { apps: [{ name: 'my_api', script: 'dist/main.js', watch: ['src'], // 仅监控源码目录变更 ignore_watch: ['node_modules', 'dist', '.git'], // 排除无需监控的目录 instances: 2, exec_mode: 'cluster', wait_ready: true, listen_timeout: 20000, kill_timeout: 5000 }] };
此配置仅在src目录代码变更时触发重启,build过程的dist目录变化不会被监控到,但可控性不如方案1。
额外优化:分离构建与运行目录(可选)
若担心build过程中删除dist影响运行,可将构建产物输出到单独目录:
1. 修改package.json的构建配置
// package.json "prebuild": "rimraf build", "build": "nest build --output build", // 指定构建输出到build目录 "start": "pm2 start ecosystem.config.js"
2. 修改ecosystem.config.js
// ecosystem.config.js module.exports = { apps: [{ name: 'my_api', script: 'build/main.js', watch: false, instances: 2, exec_mode: 'cluster', wait_ready: true, listen_timeout: 20000, kill_timeout: 5000 }] };
配合方案1的手动重载流程,可彻底避免构建过程对运行中服务的影响。
内容的提问来源于stack exchange,提问作者Mamochi
相关产品推荐
相关产品推荐

