SQLNET.EXPIRE_TIME 是服务端TCP保活探测参数,每N分钟发探测包清理已断开的空闲连接,对ORA-12170等连接建立超时无效。
sqlnet.ora 中 SQLNET.EXPIRE_TIME 是什么,真能防连接超时?
sqlnet.expire_time 并不解决客户端发起连接时的“超时”,而是用于服务端定期发送探测包(tcp keepalive),判断空闲连接是否已断开。它对 oracle rac 场景下常见的“连接突然中断但会话未释放”“负载均衡器踢掉长空闲连接”这类问题有效,但对 ora-12170: tns:connect timeout occurred 或 jdbc 连接阶段卡死完全无效。
实际生效需满足:客户端连接必须已建立、处于空闲状态、且网络中间设备(如防火墙、F5、云LB)主动回收了 TCP 连接但 Oracle 服务端还不知情。此时设为 SQLNET.EXPIRE_TIME = 10(单位分钟),服务端每 10 分钟发一次探测,发现失败则清理对应进程和会话。
- 值设太小(如 1)会增加不必要的网络探测和系统调用开销,尤其在高并发短连接场景下可能反向拖慢监听器响应
- RAC 环境中该参数需在所有节点的
$ORACLE_HOME/network/admin/sqlnet.ora中统一配置,否则部分节点无法触发清理 - 该参数不影响客户端 connect timeout、receive timeout 或 SQL 执行超时,这些由客户端驱动或
SQLNET.INBOUND_CONNECT_TIMEOUT控制
真正影响连接建立超时的是 SQLNET.INBOUND_CONNECT_TIMEOUT 和客户端侧设置
当客户端尝试连接 SCAN VIP 或单个节点 VIP 时卡住几十秒后报 ORA-12170,大概率是服务端监听器拒绝慢连接,而非网络延迟本身。Oracle 默认 SQLNET.INBOUND_CONNECT_TIMEOUT 为 60 秒,但 RAC 中若监听器响应慢(比如资源紧张、DNS 解析卡顿、ACL 检查耗时),这个阈值可能不够。
解决方法是在所有节点的 sqlnet.ora 中显式加大该值:
SQLNET.INBOUND_CONNECT_TIMEOUT = 180
注意这不是“让连接等更久”,而是给监听器留出足够时间完成身份校验、日志记录、资源分配等初始化动作。同时必须配合以下操作:
- 确认客户端连接字符串里没硬编码过短的 connect timeout(例如 JDBC 的
connect_timeout=5会直接覆盖服务端设置) - 检查 DNS 反向解析是否启用——RAC 节点名若无法被客户端正反向解析,监听器会在日志里反复尝试,拖慢整个 accept 流程
- 若使用 Oracle Wallet 或 SSL,
SQLNET.ENCRYPTION_SERVER等协商过程也会占用 inbound timeout 时间窗口
RAC 特有风险:SCAN 监听器未就绪导致连接随机超时
Oracle RAC 启动顺序中,SCAN 监听器(SCAN_LISTENER)依赖于 Clusterware 完全上线,有时比数据库实例启动晚几十秒。此时客户端连 SCAN VIP 就会遇到“连接被拒绝”或长时间等待后超时,而直连单节点 VIP 却正常。
验证方式很简单:在任意节点执行
lsnrctl status LISTENER_SCAN1
如果返回 Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN1))) 后卡住或报 TNS-12541: TNS:no listener,说明 SCAN 监听器尚未注册成功。
- 不要靠重启监听器解决——应检查
crsctl stat res -t | grep scan确认ora.scan1.vip和ora.LISTENER_SCAN1.lsnr状态是否 ONLINE - 若 SCAN VIP 飘到某节点后监听器始终起不来,常见原因是该节点 hosts 文件里 SCAN 名称解析错误,或私网心跳异常导致 OCR 读取失败
- 临时规避可改用节点 VIP 连接,但长期必须修复 SCAN 机制,否则负载均衡和故障转移失效
客户端连接池配置不当才是多数“超时”的真实根源
应用层看到的“连接超时”往往不是数据库没响应,而是连接池在获取连接时等不到可用连接。比如 HikariCP 默认 connection-timeout=30000(30 秒),但数据库侧因锁争用、归档满、AWR 快照阻塞等原因,导致新连接建立耗时超过 30 秒,池就直接抛异常。
这时调 sqlnet.ora 参数毫无意义。优先排查方向是:
- 查数据库 alert 日志,看是否有
WARNING: inbound connection timed out (ORA-3136)—— 这才是真正服务端拒绝连接的信号 - 用
netstat -an | grep :1521观察 ESTABLISHED 连接数是否接近操作系统 limit(如 Linux 默认 1024),大量 CLOSE_WAIT 表示应用没正确 close - 确认连接池 max pool size 是否远小于并发请求数,导致线程排队等待连接,表象就是“连接超时”
RAC 环境下还要额外检查服务名是否绑定到所有实例(srvctl config service -d <db></db>),如果只跑在 instance1 上,而连接池轮询到 instance2,就会触发重试逻辑,叠加超时。











