scan listener 仅做初始连接分发,非实时负载均衡;负载均衡依赖dns返回多个scan ip、服务配置clb_goal/long及goal参数,以及客户端使用scan名而非实例名连接。

SCAN Listener 是否真在分发连接?
SCAN Listener 不是“自动均衡器”,它只做初始连接分发,且默认策略是轮询(Round Robin)DNS解析结果。如果 /etc/hosts 里只写了一个 SCAN IP,或者 DNS 只返回单个 A 记录,那所有新连接都会打到同一个节点——根本没负载均衡。
- 必须确保 DNS 对
rac-scan.example.com返回至少 3 个不同 IP(对应 SCAN VIP),且这些 VIP 实际绑定在不同节点的 SCAN Listener 上 - 验证方式:在客户端执行
nslookup rac-scan.example.com,确认返回多个 IP;再用telnet <ip> 1521</ip>测试每个 VIP 是否可连 - 不要用
/etc/hosts模拟多 IP——它不触发 SCAN 的负载逻辑,仅用于测试或隔离环境
服务级负载均衡靠什么控制?
真正决定请求走向的是服务(Service)配置,不是实例本身。Oracle 不按 CPU 或会话数实时调度,而是靠服务的 CLB_GOAL 和 GOAL 参数驱动运行时重定向。
-
CLB_GOAL = SHORT:适用于短连接(如 Web 应用),要求监听器主动将新连接重定向到负载较低的实例(需客户端支持重定向) -
CLB_GOAL = LONG:适用于长连接(如 ETL、报表),只做初始分配,后续不干预 -
GOAL = THROUGHPUT或GOAL = SERVICE_TIME:影响 Oracle Net 如何评估“负载”,但前提是CLB_GOAL已启用且客户端重试机制配合 - 检查命令:
srvctl config service -d <db_name></db_name>,确认服务启用了-j SHORT选项
为什么加了节点,负载还是不均?
新增节点后未注册服务、或服务未启用跨节点漂移,会导致新节点空转。RAC 不会自动把已有连接“搬”过去,只对新连接生效。
- 新节点上线后,必须显式启动服务:
srvctl start service -d <db_name> -s <service_name> -n <new_node></new_node></service_name></db_name> - 服务需配置
-r(run on all nodes)或明确指定-n node1,node2,node3,否则默认只跑在创建时指定的节点上 - 客户端连接字符串中不能硬编码单个实例名(如
INSTANCE_NAME=rac01),必须用 SCAN 名或服务名,否则绕过所有负载逻辑 - 应用层连接池若缓存了物理连接地址(比如 Druid 的
initialSize预热时直连某实例),也会导致冷启动偏差
监控和调优的关键指标在哪?
别只看 v$session 连接数,那是静态快照;真正反映负载的是 v$servicemetric 和 v$active_services 中的每秒事务、响应时间、队列等待。
- 查服务实时负载:
SELECT service_name, busy_time, cpu_wait_time, resp_wait_time FROM v$servicemetric WHERE begin_time > SYSDATE - 1/1440; - 确认服务是否真在多节点运行:
SELECT name, failover_type, failover_method, goal FROM gv$active_services; - 发现某节点长期
busy_time高但连接数少?可能是该节点承担了高开销 SQL(如未绑定变量的硬解析),得结合gv$sql和gv$session_longops定位
实际负载不均往往卡在 DNS、服务配置、客户端连接串三处,而不是 RAC 本身“不会均衡”。调优时先验 SCAN 解析、再查服务参数、最后盯住 v$servicemetric 的实时值,比盯着 v$session 数人头有效得多。











