load_balance=on必须写在每个description块一级,紧挨address且不可嵌套于connect_data或description_list外层;ojdbc驱动忽略url中的该参数,仅依赖tnsnames.ora或scan地址实现负载均衡。

LOAD_BALANCE=on 必须写在每个 DESCRIPTION 内,不是 ADDRESS 下也不是 CONNECT_DATA 里
微服务应用连 RAC 时最常踩的坑:把 LOAD_BALANCE=on 放错位置。TNS 解析器只认它出现在 DESCRIPTION 块一级——紧挨着 ADDRESS,且不能嵌套进 CONNECT_DATA 或包在 DESCRIPTION_LIST 外层。
错误写法示例(连接永远打到第一个节点):
(DESCRIPTION_LIST =
(LOAD_BALANCE = on) ← 这里无效
(DESCRIPTION =
(ADDRESS = (PROTOCOL=TCP)(HOST=rac1-vip)(PORT=1521))
(CONNECT_DATA = (SERVICE_NAME=mydb))
)
)
正确结构必须是:
- 每个
DESCRIPTION单独配LOAD_BALANCE=on - 多个节点地址必须用
DESCRIPTION_LIST包裹 -
LOAD_BALANCE=on和ADDRESS在同一级括号内
Java 微服务别在 JDBC URL 里硬塞 LOAD_BALANCE 参数
OJDBC 驱动(包括 UCP)根本不读 URL 中的 LOAD_BALANCE。它只依赖本地 tnsnames.ora 或 Oracle Net 的解析逻辑。你在 jdbc:oracle:thin:@(DESCRIPTION=...) 里加 LOAD_BALANCE=on,驱动直接忽略。
真正生效的方式只有两种:
- 微服务所在机器部署
tnsnames.ora,内容按前述DESCRIPTION_LIST结构配置,并确保TNS_ADMIN环境变量指向该路径 - 用 SCAN 地址连接(如
jdbc:oracle:thin:@p19c-scan:1521/mydb),此时负载由 SCAN Listener 根据V$SERVICEMETRIC.CURRENT_LOAD转发,LOAD_BALANCE参数反而不需要显式写
注意:SCAN 方式要求服务端 REMOTE_LISTENER 指向 SCAN 地址,且 srvctl config listener 能查到 LISTENER_SCAN1,否则连接会 fallback 到首节点。
Server-side 负载注册失败时,Client-side 配得再对也没用
客户端随机选地址只是第一步;最终请求落到哪个实例,取决于 SCAN Listener 是否拿到各节点实时负载数据。这靠的是每个实例的 PMON 进程每 3 秒向 REMOTE_LISTENER 上报 V$SERVICEMETRIC.CURRENT_LOAD。
常见静默失败点:
-
REMOTE_LISTENER指向 VIP 或 localhost,而非 SCAN 地址(如scan.example.com:1521) - DNS 未正确解析 SCAN 名称,或 /etc/hosts 里漏了 SCAN 条目
-
lsnrctl status LISTENER_SCAN1输出中 service 条目没有load=xx字段
验证命令:srvctl config listener 看 SCAN 监听器是否存在;sqlplus / as sysdba -c "SELECT inst_name, current_load FROM gv$servicemetric ORDER BY 2;" 查各节点是否上报了负载值。
Spring Boot + UCP 连接池要关掉 auto-commit 并启用 FAN
UCP(Universal Connection Pool)本身不自动开启 Fast Application Notification(FAN),但 RAC 故障转移和负载感知严重依赖它。没开 FAN,节点宕机后连接池可能长时间保留失效连接。
关键配置项(application.yml):
spring:
datasource:
hikari:
jdbc-url: jdbc:oracle:thin:@p19c-scan:1521/mydb
# 不要设 auto-commit: true —— RAC 场景下事务边界应由业务控制
ucp:
connection-pool:
connection-factory-class-name: oracle.ucp.jdbc.PoolDataSourceFactory
url: jdbc:oracle:thin:@p19c-scan:1521/mydb
fcf-enabled: true ← 必须显式开启
ons-config: nodes=p19c-scan:6200 ← ONS 地址需与 SCAN 对应
FAN 依赖 Oracle Notification Service(ONS),若未部署独立 ONS,可直接复用 SCAN 的端口(默认 6200)。
真正决定连接是否均匀分布的,从来不是客户端写了几个 ADDRESS,而是服务端有没有持续上报负载、SCAN Listener 是否能拿到并使用这些数据。哪怕 tnsnames.ora 里写了十个节点地址,只要 REMOTE_LISTENER 配错或 DNS 解析失败,所有连接仍会扎堆在第一个可用节点上。











