fan不是简单开关,必须服务端推送down/up事件且客户端通过ons完整接收才能生效;仅设fanenabled=true无效,需验证跨节点ons互通、禁用tns层参数、确保service启用fan及连接池显式启用fcf。
fan 不是开个开关就能用的,必须让 jdbc 客户端真正收到服务端推送的 down/up 事件,否则连接池只会等超时或报 ora-03113。
为什么 setProperty("oracle.jdbc.fanEnabled", "true") 后仍无故障切换?
FAN 依赖底层 ONS(Oracle Notification Service)通道,但多数人只验证了本地 ONS 进程是否运行,没验证集群节点间能否互通:
-
onsctl ping成功 ≠ FAN 可用;必须执行onsctl ping -h rac2 -p 6113(替换为真实节点名和端口)逐节点验证跨节点通信 -
$CRS_HOME/opmn/conf/ons.config中的remoteport必须与racgons add_config注册的端口完全一致,且所有节点localport不能重复(默认 6113,冲突会导致事件丢弃) - ONS 必须由 CRS 管理启动:
crsctl start resource ora.ons;手动运行$ORACLE_HOME/bin/onsctl start会加载错误的 ONS 实例,无法接收 RAC 内部事件 - 检查
$CRS_HOME/log/<host>/client/ons.log</host>,若出现Connection refused或Failed to connect to remote host,说明 ONS 联通失败,FAN 事件根本发不出去
JDBC 连接字符串里加 FAILOVER=ON 有用吗?
没用。FAILOVER=ON 属于 TNS 层的 Connect-time Failover,只影响初始建连;而 FAN/FCF 是运行时事件驱动机制,两者互不感知:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 启用 FCF 必须显式设置:
connection.setProperty("oracle.jdbc.fanEnabled", "true")(JDBC Thin)或 UCP 中调用setFastConnectionFailoverEnabled(true) - 连接字符串中禁止含
LOAD_BALANCE=ON或FAILOVER=ON—— 这些参数会干扰 FCF 的事件响应路径,尤其在 SCAN 场景下导致连接被路由到已宕机实例 - 必须使用 SERVICE_NAME 对应 RAC 中状态为 ENABLED 的 service(查
srvctl config service -d <db></db>),且该 service 的FAILOVER_TYPE不能是 NONE,应设为SELECT或SESSION - 若用 UCP,务必关闭隐式缓存:
setImplicitCachingEnabled(false),否则 FCF 事件触发后连接不会被及时清理
SCAN 地址 + TAF 配置为何不能替代 FAN?
SCAN 提供地址发现能力,TAF 提供会话重建能力,但它们都不主动感知实例故障;只有 FAN 才能让连接池“立刻知道”某个实例挂了:
- 只配 SCAN + TAF,当实例宕机时,应用仍会继续向该实例发请求,直到 TCP 超时(通常 30–60 秒)才报错,期间大量请求阻塞或失败
- FAN 是服务端主动推送事件:RAC 检测到实例 down,立即通过 ONS 向所有注册客户端广播
DOWN事件,连接池收到后秒级清理失效连接、重建新会话 - TAF 的
FAILOVER_MODE=(TYPE=SELECT)只对正在执行的查询有效,但前提是连接还活着;FAN 则在连接断开前就介入,避免请求发往已不可达实例 - Java 应用若用 Easy Connect 格式(如
jdbc:oracle:thin:@//scan:1521/orcl),则完全无法读取 tnsnames.ora 中的 TAF 配置,更别提 FAN——必须用别名方式:jdbc:oracle:thin:@RAC,并确保TNS_ADMIN环境变量指向含正确配置的目录
最容易被忽略的是:FAN 事件不是“推一次就完事”,它需要客户端持续监听、服务端持续发布、ONS 持续中转;任意一环断开(比如某节点 ONS 配置遗漏、防火墙封了 6113 端口、应用未注册监听器),整个链路就失效——此时看起来像“配置全对却没反应”,实际是静默丢包。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










