LOAD_BALANCE=ON未生效是因为必须置于ADDRESS_LIST内而非DESCRIPTION顶层;需配合每个ADDRESS中的CONNECT_TIMEOUT=10才能实现快速故障转移,且JDBC URL中值须小写on。
LOAD_BALANCE=ON 为什么没起作用?
oracle 客户端默认不开启 tns 层负载均衡,load_balance=on 必须显式配置在 tnsnames.ora 的每个 address_list 下,而不是整个连接描述符顶层。常见错误是把它写在 (description=...) 外层,或误以为只要配了多个 address 就自动轮询。
实操建议:
-
LOAD_BALANCE=ON必须放在(ADDRESS_LIST=(LOAD_BALANCE=ON)(ADDRESS=...)(ADDRESS=...))这一级,否则被忽略 - 仅对同一
ADDRESS_LIST内的多个ADDRESS生效;跨ADDRESS_LIST(比如主备两个 list)不参与轮询 - 客户端每次新连接时随机选一个地址,不是会话内动态切换——所以短连接场景效果明显,长连接几乎看不出负载变化
- Oracle 19c 默认使用随机算法,不支持权重或哈希;想控制分发逻辑得靠应用层或连接池(如 UCP)
FAILOVER=ON 后连接还是卡住 20 秒?
默认 FAILOVER=ON 只启用故障转移,但不改变单个地址的连接超时行为。Oracle 客户端尝试第一个地址失败后,会等 TCP 层超时(通常 20–30 秒)才切到下一个,这不是 FAILOVER 配置问题,而是缺少配套的连接级超时控制。
实操建议:
- 必须同时设置
CONNECT_TIMEOUT=10(单位秒),限制单次连接尝试时长;该参数需放在每个ADDRESS内部,例如(ADDRESS=(PROTOCOL=TCP)(HOST=...)(PORT=...)(CONNECT_TIMEOUT=10)) -
RETRY_COUNT=2和RETRY_DELAY=3可减少重试总耗时,但不能替代CONNECT_TIMEOUT -
FAILOVER_MODE是可选增强项:如果要实现会话级故障转移(比如执行中实例宕机),需要额外配(FAILOVER_MODE=(TYPE=SESSION)(METHOD=BASIC)(RETRIES=3)(DELAY=5)),但这对连接建立阶段无效
tnsnames.ora 里混用 LOAD_BALANCE 和 FAILOVER 的典型结构
这两个选项可以共存,但位置和嵌套层级非常关键。错一层,要么全失效,要么只生效一个。19c 要求把它们都收束在同一个 ADDRESS_LIST 下,且顺序无关,但必须同级。
正确示例(精简版):
MYDB =
(DESCRIPTION =
(ADDRESS_LIST =
(LOAD_BALANCE = ON)
(FAILOVER = ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = srv1)(PORT = 1521)(CONNECT_TIMEOUT = 8))
(ADDRESS = (PROTOCOL = TCP)(HOST = srv2)(PORT = 1521)(CONNECT_TIMEOUT = 8))
)
(CONNECT_DATA = (SERVICE_NAME = mydb))
)
注意点:
- 不要在
DESCRIPTION外再套一层ADDRESS_LIST,也不要把LOAD_BALANCE放到CONNECT_DATA里 -
CONNECT_TIMEOUT必须重复写在每个ADDRESS中,不能只写一次 - 如果用了 SCAN 地址(如 RAC 环境),通常不需要手动配多
ADDRESS,SCAN 自带负载和故障转移,此时LOAD_BALANCE和FAILOVER反而可能干扰默认行为
Java 应用里用 JDBC URL 配置时的坑
JDBC Thin 连接串不识别 tnsnames.ora 里的别名扩展语法,也不能直接写 LOAD_BALANCE=ON。想在 URL 里模拟类似行为,只能靠 Oracle 自己的 URL 格式,而且 19c 对参数名大小写敏感。
实操建议:
- URL 必须用 Oracle 原生格式:
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=on)(FAILOVER=on)(ADDRESS=(PROTOCOL=TCP)(HOST=srv1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=srv2)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=mydb))) -
LOAD_BALANCE的值必须小写on,大写ON在某些 JDBC 驱动版本下会被忽略 - Spring Boot 的
spring.datasource.url中若含括号和等号,需确保 YAML 或 properties 文件未做意外转义;推荐用application.yml并缩进对齐,避免解析错误 - Tomcat JNDI 数据源配置里,
url属性值同样适用上述规则,但要注意 XML 实体编码(如(替代()可能导致语法失效
CONNECT_TIMEOUT 必须绑定到每个 ADDRESS,以及 JDBC URL 中大小写的隐性约束——调不通时先盯死这两处。











