Node.js项目中node-postgres数据库连接失败后重连实现求助
嘿,我来帮你搞定这个数据库重连的问题!
首先,你当前代码的问题很明确:第一次连接失败后,你在catch里再次调用了postgis.connect(),但这次新的Promise没有添加.catch()处理。如果重试再次失败,就会触发你看到的UnhandledPromiseRejectionWarning——因为这个拒绝的Promise没有被捕获。
而且,单纯固定间隔重试也不是最优方案,最好用指数退避(每次重试间隔翻倍),既不会在数据库恢复前狂刷请求,也能保证尽快重新连接。另外,还要处理连接成功后突然断开的情况,避免进程崩溃。
下面是修改后的完整代码,我会一步步解释:
const { Client } = require('pg'); // 数据库客户端实例 const postgis = new Client({ user: process.env.PGUSER, host: process.env.PGHOST, database: process.env.PGDATABASE, password: process.env.PGPASSWORD, port: process.env.PGPORT }); // 标记是否正在重连,防止重复触发重连请求 let isReconnecting = false; // 带指数退避的重连函数 function connectWithRetry(attempt = 1) { const maxAttempts = 5; // 可选:设置最大重试次数,避免无限循环 // 每次重试间隔翻倍,最多不超过60秒 const delay = Math.min(10000 * Math.pow(2, attempt - 1), 60000); console.log(`Connecting to PostGIS (${process.env.PGDATABASE}@${process.env.PGHOST}:${process.env.PGPORT}) - Attempt ${attempt}`); postgis.connect() .then(() => { console.log(`✅ PostGIS connected successfully!`); isReconnecting = false; // 重连成功后重置标记 }) .catch((e) => { console.error(`❌ Connection attempt ${attempt} failed: ${e.message}`); if (attempt < maxAttempts) { console.log(`Retrying in ${delay / 1000}s...`); setTimeout(() => connectWithRetry(attempt + 1), delay); } else { console.error(`⚠️ Max reconnection attempts (${maxAttempts}) reached. Exiting process.`); process.exit(1); // 可选:如果连不上,退出让进程管理器重启 } }); } // 监听连接断开事件,自动触发重连 postgis.on('error', (e) => { console.error(`⚠️ PostGIS connection lost unexpectedly: ${e.message}`); if (!isReconnecting) { isReconnecting = true; connectWithRetry(); } }); // 启动初始连接 connectWithRetry();
关键改进点:
- 完整的错误捕获:每次调用
connect()都有.catch()处理,不会再出现未处理的Promise拒绝警告。 - 指数退避重试:第一次等10秒,第二次20秒,第三次40秒,最多60秒,避免对数据库造成不必要的压力。
- 连接断开自动重连:通过监听
error事件,在连接意外断开时自动触发重连。 - 防重复重连:用
isReconnecting标记避免同时发起多个重连请求。 - 可配置的最大重试次数:防止数据库长期不可用时无限循环重试,可选退出进程让运维工具重启。
这样修改后,你的应用就能在数据库down的时候自动尝试重连,而且不会有那些烦人的警告啦!
内容的提问来源于stack exchange,提问作者LogaKrishnan
相关产品推荐
相关产品推荐

