Postgres重启后Node.js应用崩溃无法自动恢复该如何解决?
问题核心诱因
- Node.js应用的Postgres客户端没有配置断连自动重连逻辑,Postgres重启后原有连接失效,未捕获的连接异常直接导致应用崩溃
- 同时使用pm2和nodemon托管应用,崩溃后nodemon进入等待文件变更的挂起状态,不会自动重启服务
- pm2开启了文件监听,工作目录下的临时文件(如日志中出现的
package.json.989998446这类临时文件)变更会触发pm2反复重启应用,加剧异常
具体解决步骤
1. 新增Postgres连接异常处理与自动重连逻辑
在Node.js应用的Postgres连接初始化代码中,添加重连配置与全局异常捕获:
如果使用的是报错日志中的postgres客户端库,初始化时补充以下参数:
const sql = postgres({ host: '你的Postgres容器服务地址', port: 5432, user: '数据库用户名', password: '数据库密码', database: '数据库名', // 新增重连配置 retry: { max: 10, // 最大重试次数 delay: 2000 // 每次重试间隔2秒 }, // 捕获连接级错误,避免直接抛异常崩溃 onerror: (err) => { console.error('Postgres连接异常:', err) } })
同时在应用入口文件添加全局异常兜底处理:
// 捕获未处理的同步异常 process.on('uncaughtException', (err) => { console.error('未捕获异常:', err) }) // 捕获未处理的异步Promise异常 process.on('unhandledRejection', (err) => { console.error('未处理Promise拒绝:', err) })
2. 调整进程托管配置,避免重复托管与无效重启
生产环境无需同时使用pm2和nodemon,仅保留pm2托管即可,同时关闭pm2的文件监听:
- 先停止当前运行的pm2进程:
pm2 delete myApp - 推荐使用pm2配置文件
ecosystem.config.js启动服务,配置参考:
module.exports = { apps : [{ name: 'myApp', script: '你的应用入口文件路径,比如app.js', watch: false, // 关闭文件监听,避免临时文件触发不必要重启 autorestart: true, // 应用崩溃后自动重启 restart_delay: 3000, // 每次重启间隔3秒,等待Postgres启动完成 max_restarts: 10, // 最大连续重启次数,避免无限循环重试 env: { NODE_ENV: 'production' } }] }
- 用新配置启动应用:
pm2 start ecosystem.config.js
3. Docker层面优化启动顺序(可选,适配docker-compose部署场景)
如果用docker-compose管理两个容器,添加Postgres健康检查,保证Postgres完全启动就绪后再启动Node.js应用,docker-compose.yml参考配置:
version: '3.8' services: postgres: image: postgres:14-alpine environment: POSTGRES_USER: 你的数据库用户名 POSTGRES_PASSWORD: 你的数据库密码 POSTGRES_DB: 你的数据库名 # 添加健康检查 healthcheck: test: ["CMD-SHELL", "pg_isready -U 你的数据库用户名 -d 你的数据库名"] interval: 5s timeout: 5s retries: 5 node-app: build: ./node应用的Dockerfile目录 depends_on: postgres: condition: service_healthy # 等Postgres健康检查通过后再启动 restart: always
完成以上配置后,重启Postgres后Node.js应用要么自动重连恢复,要么崩溃后pm2会自动拉起,无需手动重启。
内容的提问来源于stack exchange,提问作者Or Zaguri
相关产品推荐
相关产品推荐

