政务系统跨网 Oracle 假死问题技术定性说明

23 阅读4分钟

政务系统跨网 Oracle 假死问题技术定性说明

一、问题背景

本系统为政务内网部署的业务系统,数据库采用多数据源架构:

  • DM 数据库:部署在政务内网服务器,与应用处于同一网络环境
  • Oracle 数据库:部署在云服务器,通过政务网络出口跨网访问

在系统正常运行期间,偶发出现以下问题:

  • 应用服务本身未宕机
  • 某些接口访问 Oracle 数据库时长时间无响应(最长约 16 分钟)
  • 连接池逐步被占满,最终导致服务不可用
  • 同一时间,访问政务内网 DM 数据库的功能完全正常

该问题在寒假等低用户访问期间出现频率显著升高


二、问题现象描述

  1. 应用日志中无明显 SQL 语法错误或数据库拒绝连接错误
  2. Oracle 数据库连接获取成功,但在执行查询时阻塞
  3. 阻塞持续时间长(约 16 分钟),之后连接才失败或恢复
  4. 连接池中的连接无法及时释放,导致新请求获取连接超时
  5. 重启应用服务后,问题可暂时消失

三、排查结论(核心定性)

该问题并非业务代码缺陷、并非连接池实现问题,也并非 Oracle 数据库本身故障。

核心结论:

这是一起典型的“政务内网系统跨网络访问云上 Oracle 数据库,在低流量场景下发生 TCP 半开(Blackhole)连接,导致 JDBC 读操作长时间阻塞”的问题。


四、问题根因分析

4.1 网络拓扑差异是根本原因

当前系统实际存在两种完全不同的访问路径:

  • 访问 DM 数据库

    • 应用服务器 → 政务内网 → 政务内网 DM 数据库
    • 无跨网、无 NAT、无云边界设备
  • 访问 Oracle 数据库

    • 应用服务器 → 政务网络出口 → 防火墙 / NAT / 云边界 → 云上 Oracle

这两种路径在网络稳定性、会话管理机制上存在本质差异。


4.2 低流量场景触发问题的原因

在用户访问量较低(如寒假)时:

  • 数据库连接长时间处于空闲状态(Idle)
  • 跨网络链路中的防火墙 / NAT / 云网关可能对空闲 TCP 会话进行静默老化处理
  • 连接在操作系统和应用层仍被认为是“有效连接”,但实际上已无法正常通信

当后续请求再次使用该连接执行 SQL 时:

  • TCP 连接不会立即报错
  • Oracle JDBC 在 socket read 阶段阻塞
  • 由于缺乏强制读超时机制,线程被长期占用

该状态在工程上称为:

TCP 半开连接(Half-open / Blackhole Connection)


4.3 为什么 DM 数据库不会出现该问题

DM 数据库部署在政务内网,具备以下特征:

  • 无跨网络访问
  • 无 NAT 会话老化问题
  • 网络链路稳定、可控

因此:

  • 连接要么可用,要么立即失败
  • 不会出现“连接存在但永远不返回数据”的状态

这也是为何同一套程序、同一连接池配置,只有 Oracle 数据源出现问题


4.4 16 分钟阻塞时间的来源说明

约 16 分钟的阻塞时间并非业务层配置,而是由以下因素共同决定:

  • 操作系统 TCP 重传与超时策略
  • Oracle JDBC 驱动默认的无限读等待机制
  • 中间网络设备对无响应连接的处理方式

因此,该时间并不固定,也不代表数据库主动断开连接。


五、问题性质定性

该问题属于:

  • 跨网络数据库访问的典型工程问题
  • 低并发、长空闲场景下更容易触发
  • 与并发量、业务压力无直接关系

不是:

  • 程序 Bug
  • SQL 设计缺陷
  • 数据库性能瓶颈

六、处理原则与治理方向(概要)

针对该类问题,行业通用处理原则为:

  1. 禁止数据库读操作无限等待
  2. 缩短连接生命周期,避免使用长时间空闲连接
  3. 在低流量场景下降低连接池保活规模
  4. 必要时通过网络或数据库中间层进行连接治理

该问题可通过工程手段规避,但无法通过单一参数彻底消除。


七、结论总结

本次问题的本质原因是:

政务内网系统通过跨网络链路访问云上 Oracle 数据库,在低流量场景下产生 TCP 半开连接,导致 Oracle JDBC 读操作阻塞,连接无法及时失效,最终引发服务假死现象。

该结论与系统架构、网络环境及实际运行特征完全一致。