在tnsnames.ora中实现VIP轮询需配置LOAD_BALANCE=ON于DESCRIPTION下,并列多个指向不同节点VIP的ADDRESS条目,端口统一为1521;不可混用VIP与SCAN,且SERVICE_NAME须与数据库实际注册名严格一致。
tnsnames.ora 里怎么写 VIP 轮询服务名
要让客户端通过 tnsnames.ora 实现对多个 oracle rac 节点 vip 的轮询连接,核心是用 load_balance=on + 多个 (address=...) 条目。不是靠服务名本身“带轮询”,而是靠客户端解析时随机选一个地址发起连接。
常见错误是只写一个 ADDRESS 却以为开了 LOAD_BALANCE 就能轮询;或者把 SCAN 地址和 VIP 混着写,导致行为不可控。
-
LOAD_BALANCE=ON必须放在ADDRESS_LIST或DESCRIPTION级别,不能只在单个ADDRESS下 - 每个
ADDRESS应指向不同节点的 VIP(不是主机名、不是 SCAN),端口统一为监听端口(通常是1521) - 不要在同一个
DESCRIPTION中混用 VIP 和 SCAN;SCAN 本身已内置负载逻辑,再套一层轮询反而干扰
示例(合法轮询配置):
MYDB =
(DESCRIPTION =
(LOAD_BALANCE = ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = node1-vip.example.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2-vip.example.com)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = mydb.example.com)
)
)
LOAD_BALANCE=ON 和 FAILOVER=ON 能不能一起开
能,但行为不叠加——FAILOVER=ON 只在连接失败时触发重试,不影响正常轮询逻辑;而 LOAD_BALANCE=ON 是每次新建连接时的随机选择策略。
容易踩的坑是误以为开了 FAILOVER 就能自动把已建立的会话“切走”,其实它只管连接建立阶段,不接管已连上的会话。
- 连接过程中某个 VIP 不通,客户端会按顺序尝试下一个
ADDRESS(前提是FAILOVER=ON) - 如果所有 VIP 都通,
LOAD_BALANCE=ON让每次sqlplus /@MYDB可能落到不同节点,但同一个会话不会中途跳转 - RAC 内部的服务均衡(如
SERVER=DEDICATED下的实例亲和性)不受此配置影响,那是服务端控制的
为什么 tnsping 显示成功,但 sqlplus 连不上
因为 tnsping 只验证网络层连通性和监听是否响应,不校验 SERVICE_NAME 是否真实注册、用户权限、甚至不检查 TNS 别名是否被正确解析到目标地址列表。
典型现象:tnsping MYDB 返回 OK,但 sqlplus 报 ORA-12514: TNS:listener does not currently know of service requested。
- 先确认
SERVICE_NAME和数据库实际注册的服务名完全一致(大小写敏感,尤其在区分大小写的 OS 上) - 检查每个 VIP 对应的监听是否真把该服务名注册进去了:
lsnrctl status输出里要有对应SERVICE_NAME - 注意客户端使用的
tnsnames.ora是哪个路径——Oracle 会按顺序查找 $TNS_ADMIN、$ORACLE_HOME/network/admin、/etc/ 等,容易读错文件
Java 应用里用 JDBC 连接 RAC,tnsnames.ora 还管用吗
不管用。JDBC Thin 驱动不读本地 tnsnames.ora,必须把完整连接描述符拼成字符串传给 DriverManager.getConnection(),或用 OracleDataSource 设置属性。
这时候轮询逻辑得靠 URL 字符串里显式列出多个地址,并开启负载参数。
- JDBC URL 示例:
jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=node1-vip)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=node2-vip)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=mydb))) - 如果用
OracleDataSource,需调用setConnectionCachingEnabled(true)并配setFastConnectionFailoverEnabled(true)才能接近 TNS 层的故障转移效果 - Spring Boot 的
spring.datasource.url直接填上面那种长 URL 即可,无需额外依赖
真正麻烦的是多环境管理——开发用单机,测试用两节点 VIP,生产用 SCAN,这些差异很难靠一套配置覆盖,得在构建或部署时替换。










