scan负载均衡需同时满足:dns返回3个a记录、tnsnames.ora中address_list包含全部3个scan地址且load_balance=on(小写)、jdbc url显式添加loadbalance=true&failover=true、使用ojdbc8+驱动、tns_admin指向正确目录并配置name.directory_path。
只写一个 scan 主机名,jdbc 就永远连不到其他节点——负载均衡根本不会触发。
tnsnames.ora 里必须显式写全三个 SCAN 地址 + LOAD_BALANCE=on
Oracle 客户端(包括 JDBC Thin)不解析 DNS 轮询结果,它只按你写的 ADDRESS_LIST 顺序尝试连接。漏掉任意一个 SCAN 条目,或把 LOAD_BALANCE=on 写成 yes/true,都会退化为直连第一个地址。
-
LOAD_BALANCE=on必须是小写on,不是布尔值;FAILOVER=on不要加在 SCAN 条目里,SCAN 本身已内置故障转移 -
HOST值必须是可被 DNS 解析的 SCAN 名称(如rac-scan.example.com),不能填 IP 或节点 VIP - 多个
ADDRESS必须包在同一个ADDRESS_LIST下,不能拆成多个独立条目 - 验证 DNS 是否返回三个 A 记录:
nslookup rac-scan.example.com,应看到三行Address:
JDBC URL 必须带 loadBalance=true&failover=true
仅靠 tnsnames.ora 里的 LOAD_BALANCE=on 不生效,JDBC 驱动需要显式参数控制行为。12c+ 的 ojdbc8.jar 才完整支持,ojdbc6 会静默忽略这些参数。
- URL 格式示例:
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=rac-scan1.example.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=rac-scan2.example.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=rac-scan3.example.com)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=orcl))(LOAD_BALANCE=on)),再追加?loadBalance=true&failover=true - 参数名必须小写,
loadBalance=true不是LOAD_BALANCE=on;大小写错误会导致参数被丢弃 - Spring Boot 中不能只在
application.properties里配spring.datasource.hikari.jdbc-url,必须把全部地址和参数拼进 URL 字符串里
TNS_ADMIN 环境变量指向目录,不是文件路径
Java 进程启动前必须设置 TNS_ADMIN,且值必须是包含 tnsnames.ora 和 sqlnet.ora 的**父目录路径**,比如 /etc/oracle/network,而不是 /etc/oracle/network/tnsnames.ora。设错则静默回退到 EZCONNECT 模式,SCAN 配置完全不加载。
-
sqlnet.ora至少要含:NAME.DIRECTORY_PATH=(TNSNAMES,EZCONNECT),否则客户端不查 tnsnames.ora - Linux 下注意 SELinux 策略和文件权限:运行 JVM 的用户必须对
tnsnames.ora有读权限,否则连接失败无明确报错 - 验证是否生效:在 Java 进程里打印
System.getenv("TNS_ADMIN"),并确认该路径下能列出两个配置文件
连接池会绕过 SCAN 负载策略,除非每个连接用独立连接串
HikariCP、Druid 等主流连接池默认复用同一套连接参数创建所有连接。如果连接池初始化时只连上了一个 SCAN 地址,后续所有连接都可能扎堆到同一个节点——即使你写了三个 SCAN,也白搭。
- 解决方案一:禁用连接池的“预热”行为,让连接在首次使用时才按 SCAN 规则建立(需查具体池的文档,如 HikariCP 的
initialization-fail-timeout=0) - 解决方案二:改用 TNSNAMES 方式 + 连接池的
connection-init-sql触发重解析(不推荐,增加延迟) - 最容易被忽略的点:连接池的
maxLifetime和idleTimeout应小于 SCAN 监听器的超时设置,否则空闲连接可能在 DNS 轮询切换后失效
SCAN 负载均衡不是 DNS 层的事,而是客户端、监听器、连接池三方协同的结果。任何一个环节没对齐参数大小写、路径权限或驱动版本,就只剩下一个节点在扛压。











