You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:48:04