fcf不是简单设参数即可生效,而是依赖服务端fan事件推送、客户端ons通信畅通、jdbc驱动识别响应的端到端链路;任一环节缺失(如service未启用failover_type=select、连接串含failover=on、ons跨节点不通或ucp未禁用隐式缓存)均导致fanenabled=true失效。

Fast Connection Failover(FCF)在 Oracle RAC 中不是“配个参数就生效”的功能,它是一条端到端链路:服务端发得出事件、客户端收得到、JDBC 驱动识别并响应。漏掉任一环,oracle.jdbc.fanEnabled=true 就只是个摆设。
服务端必须启用 FAN 且 service 状态正确
FCF 依赖 Oracle RAC 的 FAN(Fast Application Notification)事件广播,而 FAN 由 ONS(Oracle Notification Service)承载。如果服务端没开 FAN,客户端再怎么设参数也没用。
- 检查 RAC service 是否启用:
srvctl config service -d <db_name></db_name>,确认目标 service 的FAILOVER_TYPE不是NONE,且状态为ENABLED - service 必须通过
srvctl add service添加,并显式启用事件:加-e SELECT或-e SESSION(推荐-e SELECT,支持查询级故障恢复) - 确保数据库实例的
CLUSTER_DATABASE=TRUE,且监听器已注册该 service(lsnrctl status查看 service 列表中是否有该 service 及状态为READY)
客户端必须禁用 TNS 层重试逻辑
FCF 和 TNS 层的 FAILOVER / LOAD_BALANCE 是互斥机制。TNS 层配置会劫持连接行为,导致 FCF 无法接管故障检测与切换。
- tnsnames.ora 中绝对不要出现
FAILOVER=ON、LOAD_BALANCE=ON、FAILOVER_MODE等参数 - JDBC URL 应极简,例如:
jdbc:oracle:thin:@myrac-scan:1521/my_service—— 只含 SCAN 地址 + port + service name,不带任何地址列表或 failover 参数 - 若使用 UCP(Universal Connection Pool),务必调用
setFastConnectionFailoverEnabled(true);仅设connection.setProperty("oracle.jdbc.fanEnabled", "true")不生效
验证 ONS 连通性是关键断点
即使 service 和 JDBC 都对了,如果客户端连不上 ONS,FAN 事件就收不到,FCF 就卡在“静默”状态。
- 不能只跑
onsctl ping本地,必须逐节点验证远程 ONS:onsctl ping -h <node_ip> -p 6200</node_ip>(默认端口,RAC 中通常为 6200) - 检查客户端是否部署了
ons.jar(JDBC 12.2+ 已内置,但旧版需显式引入) - 确认 JVM 启动参数未屏蔽 UDP:FCF 依赖 UDP 接收 FAN 事件,防火墙或安全组必须放行 ONS 端口(6200)的 UDP 流量
UCP 连接池启用后仍不切换?查隐式缓存和服务名匹配
FCF 生效后,连接池应自动剔除失效连接并重建新连接。但常见问题不是 FCF 没触发,而是应用从缓存中取出了坏连接。
- 关闭 UCP 的隐式连接缓存:
pool.setImplicitCachingEnabled(false),否则 FCF 清理后的连接可能被缓存复用 - service 名大小写敏感,必须与
srvctl config service输出的完全一致(比如MY_SERVICE≠my_service) - 连接池获取连接时,必须使用该 service 名创建连接(如
pool.getConnection("MY_SERVICE")),而非泛用默认连接











