SCAN是Oracle RAC的统一接入入口,通过DNS轮询解析3个虚拟IP实现连接分发;不能直连节点监听因缺乏故障转移与负载感知能力,且需确保DNS配置A记录、端口开放及实例正确注册到SCAN监听。
SCAN监听是什么,为什么不能直接连节点监听?
scan(single client access name)是oracle rac对外暴露的统一接入入口,本质是一个dns轮询解析的虚拟ip集群(通常3个ip),客户端只配一个scan名就能自动分发到各节点。不直接连节点监听(如node1:1521)的关键原因是:节点故障时连接会中断,且无法感知实例负载差异;而scan配合grid infrastructure的运行时服务路由,能实现连接级的故障转移和负载感知。
常见错误现象:ORA-12170: TNS:Connect timeout occurred,多因DNS未正确配置SCAN域名解析(必须A记录,不能CNAME),或防火墙拦截了SCAN VIP所在网段的1521端口。
- DNS必须返回3个独立A记录(如
scan-rac.example.com → 192.168.10.101/102/103),不能只配1个或用CNAME - SCAN监听默认端口为
1521,需确保所有RAC节点的public网卡能互通该端口 - 检查SCAN监听状态用:
srvctl status scan_listener,不是lsnrctl status
如何验证SCAN监听已正常注册实例服务?
SCAN监听本身不直接管理数据库实例,它依赖节点上的本地监听器(LISTENER)将实例服务动态注册上来。如果srvctl status scan_listener显示正常,但客户端仍连不上,大概率是实例没注册进SCAN监听——这通常是因为实例的local_listener参数未指向本机监听器,或remote_listener没设为SCAN地址。
实操建议:
- 查实例当前注册位置:
SELECT value FROM v$parameter WHERE name = 'remote_listener';,应返回类似scan-rac.example.com:1521 - 查本地监听器是否已向SCAN广播服务:
lsnrctl services LISTENER输出中应含Service "ORCL" has 1 instance(s)且Handler(s):下有DEDICATED和established:0 refused:0 - 强制重注册实例服务:
ALTER SYSTEM REGISTER;(无需重启实例)
客户端tnsnames.ora里SCAN连接串怎么写才真正启用负载均衡?
只写SCAN地址还不够。Oracle默认使用“随机”连接策略,要真正按实例当前负载(如当前会话数、CPU使用率)做连接分发,必须启用LOAD_BALANCE=on,且禁用FAILOVER干扰(否则可能优先尝试失败节点)。
典型安全写法:
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = scan-rac.example.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
(LOAD_BALANCE = on)
)
)
关键点:
-
LOAD_BALANCE=on必须放在CONNECT_DATA内,不是ADDRESS下 - 避免混用
FAILOVER=on——它会让客户端在首次连接失败后继续试下一个地址,掩盖负载不均问题 - Java应用若用UCP连接池,需额外设置
oracle.ucp.jdbc.PoolDataSource.setConnectionPoolName("ORCL")并启用enableImplicitConnectionCache
负载真的均衡了吗?怎么确认不是“伪均衡”?
很多环境看似连SCAN就等于负载均衡,实际只是DNS轮询导致客户端连接被静态打散到不同节点,而每个客户端自身连接池长期复用同一节点,造成实例间连接数严重倾斜。真正的动态负载均衡依赖Oracle的服务(Service)机制,而非单纯SCAN。
验证方法:
- 查各节点当前连接数:
SELECT inst_id, COUNT(*) FROM gv$session GROUP BY inst_id;,对比是否接近(允许±15%) - 查服务级负载指标:
SELECT service_name, inst_id, current_conn, elapsed_time FROM gv$active_services;,current_conn才是真实活跃连接数 - 若发现某节点持续高负载,检查是否创建了单实例绑定服务(
srvctl add service -d orcl -s oltp -r orcl1),这种服务会绕过SCAN的负载逻辑
最容易被忽略的是:SCAN只解决“新连接”的分发,已有连接不会迁移;真正的业务级负载均衡需要结合服务(Service)+ 客户端连接池超时 + 应用层重试机制,而不是指望一个SCAN地址包打天下。


















