LOAD_BALANCE=on必须置于ADDRESS_LIST内层而非DESCRIPTION顶层,否则无效;客户端据此随机选择ADDRESS建立连接,仅影响新建短连接,不适用于长连接。
load_balance=on 必须放在 address_list 内部,否则完全无效。
LOAD_BALANCE=ON 为什么总不生效?
最常见的原因是把它写在了 DESCRIPTION 顶层,比如:
(DESCRIPTION = (LOAD_BALANCE = ON) (ADDRESS = ...) (ADDRESS = ...) (CONNECT_DATA = ...))
这种写法在 Oracle 19c 中会被忽略。它只对同一级的 ADDRESS_LIST 生效,且必须和 ADDRESS 并列。
-
LOAD_BALANCE=ON只作用于当前ADDRESS_LIST下的所有ADDRESS,跨ADDRESS_LIST不参与轮询 - 多个
ADDRESS必须同属一个ADDRESS_LIST,不能分散在不同ADDRESS_LIST块里 - 值必须小写:
on、yes、true都可,但 JDBC URL 中只认小写on - 客户端每次新建连接时随机选一个地址,不是轮询,也不是按负载动态调度
如何验证 Load Balance 是否真在起作用?
不能靠日志或配置“看起来对”来判断,得看实际连接落点:
- 执行
SELECT INSTANCE_NAME FROM V$INSTANCE;,返回值就是当前连接所在的实例名 - 断开重连多次(至少 5–10 次),观察返回值是否变化;如果始终一样,说明没生效
- 注意:短连接(如 JDBC 连接池每次取新连接)才能体现效果,长连接建立后不会切换节点
- 不要用
SID连接——必须用SERVICE_NAME,否则服务器端负载信息无法参与分发逻辑
LOAD_BALANCE 和 FAILOVER 能否共存?
可以,但必须严格嵌套在同一级 ADDRESS_LIST 下,顺序无关,层级错一层就失效:
(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)))
-
FAILOVER=ON控制失败后是否尝试下一个地址;LOAD_BALANCE=ON控制首次连接时是否随机选地址 - 两者逻辑独立:随机选中某个地址后,若连接失败且
FAILOVER=ON,才顺延尝试列表中下一个 - 没有
CONNECT_TIMEOUT的ADDRESS,失败后会卡住 20–30 秒才切下一个,这不是FAILOVER的问题,而是缺少超时控制
客户端负载均衡的天然局限性
它只是地址层随机,不感知节点真实负载:
- 短时间内并发大量连接,可能全落到同一节点上
- 无法避开已过载或响应缓慢的实例(除非配合
CONNECT_TIMEOUT快速剔除) - 不支持权重、哈希等策略,Oracle 官方不提供配置接口,想精细控制得靠应用层或 UCP 这类连接池
- 如果你发现连接分布严重不均,别急着调参数——先确认是不是短连接频次不够、或者
ADDRESS_LIST结构写错了


















