SCAN地址必须写全三个且JDBC URL显式启用loadBalance=true和failover=true,否则负载均衡失效;tnsnames.ora方式更稳定但TNS_ADMIN须指向父目录;连接池配置不当亦会导致RAC负载策略失效。
SCAN地址必须写全,不能只写一个
oracle rac的scan(single client access name)本质是三个ip轮询的dns别名,但jdbc驱动不会自动做dns负载均衡——它只按你写的顺序连第一个。如果你只配一个scan-hostname,连接永远只会打到其中一台节点,load_balance=on完全失效。
实操建议:
- 在
tnsnames.ora里定义多个SCAN条目(如rac-scan1、rac-scan2、rac-scan3),或直接在JDBC URL里拼接全部三个SCAN IP或主机名 - 确保DNS能正确解析所有SCAN名称(用
nslookup rac-scan验证是否返回三个A记录) - 不要依赖“SCAN名字能解析”就认为OK——JDBC驱动不查SRV记录,只走A记录+硬编码顺序
JDBC URL里必须显式启用LOAD_BALANCE和FAILOVER
LOAD_BALANCE=on不是默认开启的,光写在tnsnames.ora里也不生效,JDBC驱动需要在URL参数中明确声明,否则所有连接都扎堆到第一个地址。
常见错误现象:连接池初始化时卡住、部分节点CPU飙升、ORA-12170: TNS:Connect timeout反复出现(因为第一个SCAN节点挂了但驱动没切)
实操建议:
- URL格式必须包含
?loadBalance=true&failover=true(注意是小写true,不是on) - Oracle JDBC Thin驱动从12c起才完整支持RAC多地址负载均衡,旧版(如ojdbc6)会忽略
loadBalance参数 - 避免混用
oracle.jdbc.url和javax.sql.DataSource配置方式——后者可能绕过URL参数解析
tnsnames.ora方式更稳定,但路径和权限常被忽略
比起纯URL拼接,用tnsnames.ora文件配合TNS_ADMIN环境变量是Oracle官方推荐方式,尤其适合复杂RAC拓扑。但它对路径敏感,且JDBC驱动只读取一次。
使用场景:需要动态切换不同RAC集群、或连接串含大量冗余参数(如RETRY_COUNT、CONNECT_TIMEOUT)
实操建议:
-
TNS_ADMIN必须指向包含tnsnames.ora的**父目录**,不是文件路径本身(例如/etc/oracle/network,而非/etc/oracle/network/tnsnames.ora) - 文件里每个SCAN条目需独立命名,并在URL中引用该别名:
jdbc:oracle:thin:@my-rac-cluster - Java进程启动前必须设置
TNS_ADMIN,Spring Boot的application.properties里设无效 - Linux下注意SELinux或文件权限:JVM用户必须有读取
tnsnames.ora的权限,否则静默失败
连接池配置不当会让RAC负载策略彻底失效
即使JDBC URL和SCAN都配对了,如果连接池(如HikariCP、Druid)把所有连接都复用到同一个物理连接上,RAC的负载分发就形同虚设。
性能影响:单节点压力过大,其余节点空闲;故障转移延迟变长(连接池缓存了已断开的连接)
实操建议:
- 禁用连接池的“连接测试”或改用轻量级校验(如
SELECT 1 FROM DUAL),避免每次取连接都触发重连逻辑 - 设置
maxLifetime小于RAC的SQLNET.EXPIRE_TIME(通常设为1800秒),防止连接在池中存活太久后被RAC主动断开 - 不要设置过大的
maximumPoolSize——RAC节点数有限,盲目扩池反而加剧单点争用
SCAN地址数量、JDBC参数大小写、TNS_ADMIN路径层级、连接池生命周期这四点,任何一个出错都会让LOAD_BALANCE=on变成摆设。最常被跳过的其实是DNS解析验证和TNS_ADMIN父目录规则——连不上时先nslookup和ls -l比改代码快得多。










