ORA-12170连接超时主因是DNS解析延迟,非数据库故障;应优先用nslookup/dig测DNS响应,改hosts或sqlnet.ora中NAMES.DIRECTORY_PATH添加HOSTNAME,Java应用需注意JDBC不读sqlnet.ora。
ORA-12170 连接超时但服务端正常?先查 DNS 解析是否卡住
oracle 客户端连接慢,十次里有七次是 tnsnames.ora 里写的主机名没被及时解析,尤其在跨网段、用内网 dns 或 hosts 未覆盖的场景。现象是客户端卡 5–30 秒后报 ora-12170: tns:connect timeout occurred,而 sqlplus /@mydb 立即失败或成功——说明不是数据库问题,是名字解析环节拖住了。
实操建议:
- 用
nslookup mydb.example.com或dig mydb.example.com测 DNS 响应时间,超过 2 秒就要怀疑 - 临时绕过 DNS:把
tnsnames.ora中的主机名换成 IP 地址,再试连接;若秒连,基本锁定 DNS - 检查本地
/etc/hosts(Linux/macOS)或C:\Windows\System32\drivers\etc\hosts(Windows),补上对应条目,格式如:192.168.10.5 mydb.example.com
sqlnet.ora 的 NAMES.DIRECTORY_PATH 配置顺序很关键
Oracle 客户端默认按 NAMES.DIRECTORY_PATH 列出的顺序尝试解析方式,常见值是 (TNSNAMES, EZCONNECT),但它没包含 HOSTNAME —— 而这个才是跳过 DNS、直走系统 gethostbyname()(会查 hosts + 本地 resolver)的关键项。
实操建议:
- 在
$ORACLE_HOME/network/admin/sqlnet.ora中显式设置:NAMES.DIRECTORY_PATH = (HOSTNAME, TNSNAMES, EZCONNECT) - 删掉
SQLNET.EXPIRE_TIME(除非真需要保活),它会在空闲连接上发 probe,反而增加首次连接延迟 - 确认
SQLNET.AUTHENTICATION_SERVICES不含(NTS)(Windows 域认证),这在非域环境会额外触发安全子系统查询,拖慢数秒
tnsnames.ora 里加 TIMEOUT 参数未必有用,得看 Oracle 版本
CONNECT_TIMEOUT 和 RECV_TIMEOUT 是 12cR1 起才真正生效的参数,老版本(如 11g)写进去也不起作用,还可能因语法不识别导致解析失败。而且它们只控制 TCP 层超时,对 DNS 卡顿无效。
实操建议:
- 12c+ 可加:
(CONNECT_TIMEOUT=5)(RECV_TIMEOUT=10),放在ADDRESS段内,例如:(ADDRESS=(PROTOCOL=TCP)(HOST=mydb.example.com)(PORT=1521)(CONNECT_TIMEOUT=5)) - 11g 及更早版本,别写这些参数;靠改
/etc/resolv.conf的timeout:和attempts:更实际 - 避免在
tnsnames.ora中混用大小写主机名(如MyDB.example.com),某些 DNS resolver 对大小写敏感,导致缓存未命中
Java 应用连 Oracle 慢?注意 JDBC URL 和驱动行为差异
JDBC Thin 驱动默认不读 sqlnet.ora,它的 DNS 行为由 JVM 和 OS 控制;而 OCI 驱动会读。很多 Java 同学调了半天 sqlnet.ora,结果发现根本没生效。
实操建议:
- JDBC URL 中直接写 IP:
jdbc:oracle:thin:@192.168.10.5:1521/ORCL,比依赖 DNS 可靠 - 加 JVM 参数强制禁用 IPv6 解析:
-Djava.net.preferIPv4Stack=true,避免 dual-stack lookup 卡住 - Oracle JDBC driver 21c+ 支持
connectTimeout属性,URL 写成:jdbc:oracle:thin:@//192.168.10.5:1521/ORCL?connectTimeout=5000
真正卡住的地方往往不在数据库本身,而在客户端发起连接前那几毫秒的“找地址”动作。DNS 缓存未命中、hosts 缺失、sqlnet.ora 配置顺序错位、JDBC 驱动忽略配置——这些点都容易漏查。动手前,先用 nslookup 和 strace -e trace=connect,getaddrinfo(Linux)盯住系统调用,比翻日志快得多。










