Nest JS - TypeORM 数据库连接持久化问题:防火墙致连接中断
TypeORM 防火墙导致连接1天后断开的解决方案
一、维持连接不中断(优化保活策略)
1. 修正数据库保活配置
很多时候默认的keepAlive参数不生效是因为配置位置或参数值不对,针对不同数据库调整TypeORM的extra配置:
MySQL/MariaDB:
const dataSource = new DataSource({ type: 'mysql', host: 'your-db-host', port: 3306, username: 'user', password: 'pass', database: 'db', // 其他配置... extra: { keepAliveInitialDelay: 300000, // 5分钟后启动心跳(需大于防火墙超时检测间隔) keepAliveInterval: 60000, // 每分钟发送一次心跳包 connectTimeout: 10000, }, });同时需确保数据库端的
wait_timeout和interactive_timeout设置大于防火墙的24小时超时(例如设为25*3600秒)。PostgreSQL:
extra: { keepalives_idle: 300, // 5分钟无活动后发送心跳(单位:秒) keepalives_interval: 60, // 心跳间隔(单位:秒) keepalives_count: 5, // 重试次数 }
2. 主动定时心跳查询
如果数据库原生保活仍被防火墙阻断,可手动定时执行轻量查询维持连接:
// 连接初始化成功后启动定时任务 let heartbeatInterval; dataSource.initialize().then(() => { heartbeatInterval = setInterval(async () => { try { // 执行无副作用的轻量查询 await dataSource.query('SELECT 1'); } catch (err) { console.warn('心跳检测失败,连接可能已断开:', err.message); } }, 300000); // 每5分钟执行一次,间隔需小于防火墙超时时间 }); // 应用关闭时清理定时任务 process.on('SIGINT', () => { clearInterval(heartbeatInterval); dataSource.destroy(); });
二、断开后自动重连
1. 启用TypeORM内置重试机制
在数据源配置中直接开启重连参数:
const dataSource = new DataSource({ // 基础配置... reconnectAttempts: 15, // 最大重试次数 reconnectInterval: 5000, // 每次重试间隔5秒 });
2. 监听连接事件手动重连(更可靠)
内置重试可能无法覆盖所有场景,可通过监听连接事件实现自定义重连逻辑,加入防抖避免重复触发:
let isReconnecting = false; const reconnect = async () => { if (isReconnecting) return; isReconnecting = true; try { if (!dataSource.isInitialized) { await dataSource.initialize(); console.log('数据库连接重连成功'); } } catch (err) { console.error('重连失败,5秒后重试:', err.message); setTimeout(reconnect, 5000); } finally { isReconnecting = false; } }; // 监听连接错误与断开事件 dataSource.on('error', reconnect); dataSource.on('disconnected', reconnect);
内容的提问来源于stack exchange,提问作者Kaan Baytan
相关产品推荐
相关产品推荐

