政务系统跨网 Oracle 假死问题技术定性说明
一、问题背景
本系统为政务内网部署的业务系统,数据库采用多数据源架构:
- DM 数据库:部署在政务内网服务器,与应用处于同一网络环境
- Oracle 数据库:部署在云服务器,通过政务网络出口跨网访问
在系统正常运行期间,偶发出现以下问题:
- 应用服务本身未宕机
- 某些接口访问 Oracle 数据库时长时间无响应(最长约 16 分钟)
- 连接池逐步被占满,最终导致服务不可用
- 同一时间,访问政务内网 DM 数据库的功能完全正常
该问题在寒假等低用户访问期间出现频率显著升高。
二、问题现象描述
- 应用日志中无明显 SQL 语法错误或数据库拒绝连接错误
- Oracle 数据库连接获取成功,但在执行查询时阻塞
- 阻塞持续时间长(约 16 分钟),之后连接才失败或恢复
- 连接池中的连接无法及时释放,导致新请求获取连接超时
- 重启应用服务后,问题可暂时消失
三、排查结论(核心定性)
该问题并非业务代码缺陷、并非连接池实现问题,也并非 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 设计缺陷
- 数据库性能瓶颈
六、处理原则与治理方向(概要)
针对该类问题,行业通用处理原则为:
- 禁止数据库读操作无限等待
- 缩短连接生命周期,避免使用长时间空闲连接
- 在低流量场景下降低连接池保活规模
- 必要时通过网络或数据库中间层进行连接治理
该问题可通过工程手段规避,但无法通过单一参数彻底消除。
七、结论总结
本次问题的本质原因是:
政务内网系统通过跨网络链路访问云上 Oracle 数据库,在低流量场景下产生 TCP 半开连接,导致 Oracle JDBC 读操作阻塞,连接无法及时失效,最终引发服务假死现象。
该结论与系统架构、网络环境及实际运行特征完全一致。