Oracle 19c RAC连接负载均衡需Client-side与Server-side协同生效:Client-side要求LOAD_BALANCE=on置于每个DESCRIPTION内(非顶层或CONNECT_DATA),且多ADDRESS须用DESCRIPTION_LIST包裹并分别配置;Server-side依赖REMOTE_LISTENER指向SCAN地址、PMON每3秒上报V$SERVICEMETRIC.CURRENT_LOAD,缺一则连接全打首节点。
oracle 19c rac 的连接负载均衡必须 client-side 和 server-side 同时生效,缺一不可;只配一边,连接大概率全打到第一个节点。
tnsnames.ora 中 LOAD_BALANCE=on 必须放在 DESCRIPTION 级别
客户端不显式启用,TNS 解析器根本不会做地址随机选择。很多人把 LOAD_BALANCE=on 错误地塞进 CONNECT_DATA 或漏写在多 ADDRESS 场景下,导致配置无效。
-
LOAD_BALANCE=on必须紧邻ADDRESS所在的DESCRIPTION块内,且只能出现在该层级——放错括号位置(比如包在DESCRIPTION_LIST外或嵌套进CONNECT_DATA)完全不生效 - 如果用了多个
ADDRESS(例如直连两个 VIP),必须用DESCRIPTION_LIST包裹多个独立的DESCRIPTION,每个都要单独加LOAD_BALANCE=on,否则仅第一个地址参与轮选 - Java 应用走 UCP 或 OJDBC 时,该参数仍由本地 TNS 解析驱动读取,
jdbc:oracle:thin:@...URL 里加任何 LB 参数都无效 - 示例正确结构:
MYDB = (DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1521))
(LOAD_BALANCE = on)
(CONNECT_DATA = (SERVICE_NAME = mydb))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1521))
(LOAD_BALANCE = on)
(CONNECT_DATA = (SERVICE_NAME = mydb))
)
)
Server-side 负载依赖 REMOTE_LISTENER + PMON 主动注册
Client-side 只是“随机挑一个地址发请求”,真正决定这个请求最终落到哪个实例的,是 SCAN Listener 是否能拿到各节点实时负载数据——这靠的是每个实例的 REMOTE_LISTENER 设置和 PMON 的主动上报。
- 检查命令:
srvctl config listener确认 SCAN 监听器存在;lsnrctl status LISTENER_SCAN1查看输出中是否有 service 条目带LOAD字段(如service_handler="DEDICATED", load=12),没有说明注册失败 -
REMOTE_LISTENER必须指向 SCAN 地址(如scan.example.com:1521),不是单个 VIP 或 localhost;若用了 GNS,则必须指向 GNS VIP,否则静默失败 - 修改后必须立即执行:
ALTER SYSTEM REGISTER;—— 否则 PMON 不会立刻推送新负载,可能延迟数分钟甚至更久 - 常见错误现象:tnsping 和 lsnrctl status 都显示正常,但所有连接始终只到 node1,
V$SERVICEMETRIC查询current_load全为 0 或 NULL,基本就是注册没成功
FAILOVER_MODE 会干扰负载分发逻辑
哪怕只是写了 FAILOVER_MODE=(TYPE=select),只要它存在于 tnsnames.ora 的同一 DESCRIPTION 下,就会让 Oracle 客户端优先走故障转移路径,跳过负载均衡的地址选择逻辑。
- ORA-12545、连接反复重试、或连接明显偏向某节点,往往不是网络问题,而是
FAILOVER_MODE和LOAD_BALANCE=on混用触发了冲突行为 - 如果业务确实需要 TAF(透明应用故障转移),应改用服务端方式:通过
srvctl add service -d <db> -s <svc> --taf创建带 TAF 属性的服务,并在客户端只连该 service_name,避免客户端配置FAILOVER_MODE - 验证是否被干扰:临时注释掉 tnsnames.ora 中整个
FAILOVER_MODE块,用 sqlplus 连几次,观察v$session.inst_id分布是否变均匀
最易被忽略的一点:SCAN 监听器本身不存储负载数据,它只转发请求;而每个实例的 PMON 每 3 秒向 SCAN Listener 上报一次当前连接数(V$SERVICEMETRIC.CURRENT_LOAD),这个值若长期为 0 或远低于实际连接数,说明 REMOTE_LISTENER 指向错误或监听器未监听对应端口——此时 client-side 再怎么配,server-side 负载决策也无从谈起。


















