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

NodeJS使用oracledb连接Oracle报ORA-03135连接丢失如何排查

现有代码存在的问题
  • 未使用官方推荐的连接池模式,每次新建独立连接缺少生命周期管理,闲置连接被断开后没有自动恢复机制
  • 未配置TCP保活、连接有效性校验参数,无法感知连接已经被数据库、中间网络设备断开的状态
  • 没有连接失败重试逻辑,单次连接异常就直接中断业务
  • 未设置连接超时阈值,异常场景下可能长时间挂起
故障排查方向

数据库侧排查

  • 检查数据库告警日志、监听日志,定位报错时间点的记录,确认是否存在会话被主动kill、连接数打满、IDLE_TIMEOUT/SESSION_MAX_IDLE_TIME等资源限制触发的断连
  • 确认近期数据库是否做过版本升级、参数调整、重启操作,是否调整过密码校验规则、连接白名单策略
  • 核对数据库服务端SQLNET.ALLOWED_LOGON_VERSION_SERVER参数是否与当前使用的oracledb驱动版本兼容

网络链路排查

  • telnet仅能验证TCP三次握手正常,无法验证Oracle协议层连通性,需排查链路中间的防火墙、NAT网关、负载均衡、WAF/IPS设备:
    • 确认是否配置了TCP会话闲置超时策略,超时后自动拆除连接且不向两端发送断开通知
    • 确认近期是否更新过安全规则,存在拦截Oracle数据库协议流量的策略
  • 在应用所在服务器上使用sqlplus客户端,使用完全相同的连接参数建立连接,闲置5-10分钟后执行select 1 from dual验证是否复现断连,排除应用代码本身问题

客户端侧修复与验证

  1. 优先升级oracledb驱动到最新稳定版,排除已知的驱动兼容bug
  2. 替换原有直连逻辑为连接池模式,补充保活、连接校验、重试配置,参考代码如下:
const oracledb = require('oracledb');
// 全局配置BLOB读取为Buffer
oracledb.fetchAsBuffer = [oracledb.BLOB];
// 开启TCP层保活探测
oracledb.tcpKeepAlive = true;
// 新建连接超时时间10秒
oracledb.connectionTimeout = 10000;

// 应用启动时初始化连接池
async function initDbPool() {
  await oracledb.createPool({
    user: 'mysuser',
    password: 'mypass',
    connectString: '10.xxx.xx.xxx/MYORCLID',
    poolMin: 2,
    poolMax: 10, // 根据业务并发量调整
    poolIncrement: 1,
    // 连接闲置超时时间,需短于数据库、网络设备的闲置超时阈值
    poolTimeout: 600,
    // 每60秒对池内闲置连接做活性探测,自动剔除失效连接
    poolPingInterval: 60,
    poolPingTimeout: 3000
  });
}

// 业务侧获取可用连接
async function getValidConnection() {
  let conn = null;
  // 最多重试2次,规避偶发闪断
  for (let retryCount = 0; retryCount < 3; retryCount++) {
    try {
      conn = await oracledb.getConnection();
      // 执行探测SQL确认连接可正常执行语句
      await conn.execute('select 1 from dual');
      return conn;
    } catch (err) {
      // 已建立的连接主动关闭释放资源
      if (conn) {
        try { await conn.close(); } catch (e) {}
      }
      // 非连接断开类错误直接抛出,不重试
      const errMsg = err.message || '';
      if (!errMsg.includes('ORA-03135') && !errMsg.includes('ORA-03114')) {
        throw err;
      }
      // 最后一次重试失败直接抛出
      if (retryCount === 2) throw err;
      // 等待1秒后重试
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }
}
  1. 检查应用服务器操作系统的TCP保活参数(Linux下对应net.ipv4.tcp_keepalive_time、net.ipv4.tcp_keepalive_intvl、net.ipv4.tcp_keepalive_probes),确认参数配置合理,避免保活探测间隔过长无法及时维持连接。

内容的提问来源于stack exchange,提问作者WitnessTruth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:09:10