使用connect-pg-simple时RDS重启后间歇性出现ECONNREFUSED连接错误
我们部署在AWS上的应用使用connect-pg-simple npm包做会话管理,会话数据存储于AWS RDS中。RDS重启后,应用无法正常连接RDS,间歇性出现以下错误:
Failed to prune sessions: connect ECONNREFUSED ip_address:5432
Failed to prune sessions: connect ECONNREFUSED ip_address:5432
Error: connect ECONNREFUSED ip_address:5432
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16)
Error: connect ECONNREFUSED ip_address:5432
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16)
应用实现代码如下:
let session = require('express-session'); let pgSession = require('connect-pg-simple')(session); const pg = require('pg'); const sessionPool = new pg.Pool({ host: process.env.DB_HOST, port: process.env.DB_PORT, user: process.env.DB_USERNAME, password: dbPass, database: "bludb", max: 100 }); let sessionOptions = { secret: "secret", resave: false, saveUninitialized: false, store: new pgSession({ pool: sessionPool, ttl: process.env.SESSION_TIMEOUT / 1000, createTableIfMissing: true, pruneSessionInterval: 1800 }) }; app.use(session(sessionOptions));
- 连接池未配置自动失效回收与重连
pg.Pool默认不会自动清理RDS重启后失效的旧连接,应用会持续复用这些死连接导致报错。需要给连接池添加超时配置,并监听错误事件主动回收失效连接:
const sessionPool = new pg.Pool({ host: process.env.DB_HOST, port: process.env.DB_PORT, user: process.env.DB_USERNAME, password: dbPass, database: "bludb", max: 100, idleTimeoutMillis: 30000, // 空闲连接30秒后自动回收 connectionTimeoutMillis: 2000 // 连接超时2秒后触发重试逻辑 }); // 监听连接错误,强制回收失效连接 sessionPool.on('error', (err, client) => { console.error('数据库连接异常,回收失效连接:', err); client.release(true); // 标记该连接为失效,不返回连接池 });
- 定时清理任务未处理连接失败
pruneSessionInterval配置的定时清理任务在RDS重启后会因无可用连接抛出未捕获错误。可以通过pruneSessionCallback捕获错误,并触发连接池重置:
store: new pgSession({ pool: sessionPool, ttl: process.env.SESSION_TIMEOUT / 1000, createTableIfMissing: true, pruneSessionInterval: 1800, pruneSessionCallback: (err) => { if (err) { console.error('会话清理失败:', err); // 重置连接池,强制创建新连接 sessionPool.end().then(() => { sessionPool.connect(); }).catch(reinitErr => { console.error('连接池重置失败:', reinitErr); }); } } })
AWS网络与RDS配置检查
确认RDS重启后安全组规则未变更:应用所在的EC2/ECS/EKS实例安全组需允许访问RDS的5432端口;检查RDS的私有/公有访问配置是否正常,若使用域名连接,确认DNS解析未出现异常。连接池大小超出RDS限制
max:100的连接数可能超过RDS实例的默认连接上限(如t2.micro实例默认仅66个连接),RDS重启后连接数被占满导致新连接被拒绝。可降低max值,或调整RDS参数组中的max_connections配置。
内容的提问来源于stack exchange,提问作者Anubhav Nigam

