ucp实现oracle高可用的核心是启用fan与ons联动:必须显式调用setfastconnectionfailoverenabled(true),配置ons节点(如nodes=host1:6200,host2:6200),使用scan或多地址连接串,并确保数据库端已启用fan,否则池无法感知故障并自动切换。

UCP(Universal Connection Pool)是 Oracle 官方提供的轻量级、与 JDBC 兼容的连接池实现,专为 Oracle 数据库高可用场景设计。它本身不依赖 Web 容器或应用服务器,但能原生集成 Oracle RAC、Data Guard 和 Fast Application Notification (FAN),这是它和 HikariCP、DBCP 等通用池的关键区别。
直接说结论:用 UCP 配置 Oracle 高可用连接池,核心不是“怎么建池”,而是“怎么让池感知故障并自动切换”——这取决于你是否启用并正确配置了 FAN 和 ONS,而不是单纯调大 maxPoolSize 或加重试逻辑。
UCP 必须启用 FAN 才能响应 RAC 故障转移
很多团队把 UCP 当成普通连接池用,只配了 setURL、setUsername、setPassword,结果 RAC 节点宕机后连接仍卡在失效节点上,超时才失败。根本原因是没开启 FAN 监听。
-
FAN是 Oracle 通过 ONS(Oracle Notification Service)广播的实时事件(如实例上线/下线、服务启停),UCP只有订阅了 ONS 才能秒级剔除失效连接、重路由新连接 - 必须在 UCP 配置中显式启用:
setFastConnectionFailoverEnabled(true) - 必须提供 ONS 配置:通过
setONSConfiguration指向oraaccess.xml或直接传入键值对(如"nodes=host1:6200,host2:6200") - 确保数据库端已启用 FAN:
srvctl modify service -d db_name -s svc_name -f(-f 表示启用 FAN)
连接字符串必须用 SCAN 或多个 ADDRESS,不能写单节点 TNS
如果 UCP 的 setURL 里只写一个 IP+端口(比如 jdbc:oracle:thin:@192.168.1.10:1521/ORCL),即使开了 FAN,池也无法做负载均衡或故障转移——它根本不知道其他节点在哪。
- 正确做法是使用 Oracle 推荐的连接描述符:SCAN 地址(RAC 环境)或含多个
ADDRESS的DESCRIPTION_LIST - 示例(SCAN):
jdbc:oracle:thin:@scan-host:1521/ORCL - 示例(多地址):
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=rac1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=rac2)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=ORCL))) - 避免使用
tnsnames.ora文件方式——UCP 不自动读取本地 tnsnames,除非你手动加载并解析后传入 URL
setValidateConnectionOnBorrow(false) 是陷阱,别关活检
有人为了“提升性能”把连接校验关掉,结果在 RAC 切换后大量连接持续失败,应用报 IO Error: Connection reset 或 ORA-01033。
-
UCP默认开启连接校验(validateConnectionOnBorrow=true),且校验逻辑会结合 FAN 状态:如果 FAN 已通知某节点失效,校验会直接跳过该节点上的连接 - 关闭校验后,池会把已失效的连接继续借出,直到执行 SQL 时才暴露问题,延迟故障发现、加重应用层异常处理负担
- 真正影响性能的是校验 SQL —— 不要用
SELECT 1 FROM DUAL,改用 Oracle 的轻量级验证:setSQLForValidateConnection("SELECT SYS_CONTEXT('USERENV','SESSIONID') FROM DUAL"),它走内存上下文,无 IO
ONS 配置错误导致 FAN 失效,但日志几乎不报错
UCP 启动时若 ONS 连接失败,只会静默降级为普通池(无 FAN),不会抛异常、也不打 ERROR 日志——只在 FINE 级别输出类似 UCP-ONSDiscovery: Failed to connect to ONS node,极易被忽略。
- 务必开启 JDK 日志并过滤
oracle.ucp和oracle.ons包路径,级别设为FINE或FINER - 检查 ONS 端口(默认 6200)是否在数据库服务器开放,且客户端能 telnet 通;RAC 环境中 ONS 进程需在所有节点运行(
ps -ef | grep ons) - oraaccess.xml 中的
<ons></ons>配置必须与实际 ONS 节点一致,且文件需放在类路径根目录(如src/main/resources/oraaccess.xml) - 验证 FAN 是否生效:用
sqlplus连库后执行EXEC DBMS_SERVICE.MODIFY_SERVICE(service_name=>'ORCL', failover_method=> 'BASIC'),观察 UCP 日志是否出现FAN event received: DOWN
FAN 和 ONS 的联动机制是 UCP 实现高可用的隐性骨架——看不见摸不着,但一旦配置偏差,整个高可用就形同虚设。最容易被跳过的其实是 ONS 连通性验证和日志级别调整,而不是代码写几行。











