oracle rac负载均衡失效主因是tns层load_balance=on未置于address_list内、remote_listener注册失败或scan未返回多地址;jdbc的loadbalance=true仅影响新建连接选择,不控制运行时请求分发。

Oracle RAC负载均衡失效,90%以上情况不是应用或连接池配置错了,而是TNS解析层根本没触发随机选节点逻辑——关键看LOAD_BALANCE=on是否在ADDRESS_LIST内部、remote_listener是否注册成功、SCAN是否返回多地址。
tnsnames.ora 或 JDBC URL 中的 LOAD_BALANCE=on 放错位置
Oracle 客户端负载均衡不依赖 JDBC 的 loadBalance=true,而依赖 TNS 描述符里 LOAD_BALANCE=on 是否生效。它必须出现在 ADDRESS_LIST= 的括号内,否则被忽略。
- 错误写法(
LOAD_BALANCE在DESCRIPTION层):(DESCRIPTION=(LOAD_BALANCE=on)(ADDRESS=(PROTOCOL=TCP)(HOST=rac1-vip)(PORT=1521))...)→ 不生效 - 正确写法(嵌套在
ADDRESS_LIST内):(ADDRESS_LIST=(LOAD_BALANCE=on)(ADDRESS=(PROTOCOL=TCP)(HOST=rac1-vip)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=rac2-vip)(PORT=1521))) - 用 SCAN 地址时,JDBC URL 必须显式写出完整 TNS 结构,不能只写
jdbc:oracle:thin:@rac-scan:1521/service—— 那样会跳过ADDRESS_LIST解析,LOAD_BALANCE彻底失效 - 验证方式:在客户端执行
tnsping SERVICE_NAME,看输出里是否列出多个 IP;若只返回一个,说明 TNS 解析没走 LB 路径
remote_listener 未配置或注册失败
remote_listener 是服务器端向 SCAN listener 注册实例负载信息的关键参数。如果它没设,或指向的地址不可达、DNS 解析失败,SCAN 就收不到该实例的注册信息,自然无法分发连接。
- 检查命令:
SELECT value FROM v$parameter WHERE name = 'remote_listener';
正常应返回类似LISTENERS_CLUSTER或scan-cluster:1521 - 确认注册状态:
lsnrctl status LISTENER_SCAN1(或对应 SCAN listener 名),看目标服务下是否显示两个及以上Instance条目 - 常见坑:
–remote_listener值用了主机名但未在所有节点的/etc/hosts或 DNS 中解析
– SCAN VIP 所在网段与节点 VIP 不在同一子网,导致注册包被丢弃
–LOCAL_LISTENER配置错误,间接导致remote_listener注册失败
连接池预热导致 LB 表象失效
连接池(如 HikariCP、UCP)启动时批量建连,若此时 TNS 解析结果固定(比如 DNS 缓存未刷新、SCAN 返回 IP 顺序不变),所有初始连接会落到同一实例——这不是 LB 失效,而是“一次性随机”被缓存放大了。
- 典型现象:
应用刚启动时v$session全在inst_id=2;运行几小时后仍不分散;但手动重启连接池或清空 DNS 缓存后重试,分布变均匀 - 临时缓解:
– 启动前执行sudo systemd-resolve --flush-caches(Linux)或ipconfig /flushdns(Windows)
– 在连接池配置中禁用预热:如 HikariCP 设置initialization-fail-timeout=-1+minimum-idle=0 - 注意:
loadBalance=true在 JDBC URL 中仅影响新建连接的地址选择,对已建立连接无任何重路由能力——连接复用后,所有 SQL 都走原实例,和 LB 无关
误把连接级 LB 当成请求级 LB
RAC 的负载均衡是连接建立时决定节点,不是每条 SQL 请求都重新调度。很多人查 v$session 发现连接分布不均就断定 LB 失效,其实可能只是连接池长期复用旧连接,没触发新连接创建。
- 真正要观察的指标是:
– 新建连接是否分散(查应用启动后 1 分钟内的v$session)
– AWR 报告中 “RAC Statistics” 页的gc cr blocks received和gc current blocks received是否跨节点均衡
– 实时查gv$sysstat,别漏掉inst_id过滤,否则各节点数据被 sum 在一起,掩盖倾斜 - 容易忽略的点:
–CLB_GOAL设为LONG时,监听器会参考goodness值(由 MMON 计算)做加权分配,不是纯随机;若某节点goodness异常高(如因慢 SQL 积压),新连接会被主动避开它
– ONS(Oracle Notification Service)未运行,会导致goodness值无法及时同步,LB 退化为静态轮询











