Oracle 监听器工作原理与配置

Oracle 监听器工作原理与配置

适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

Listener(监听器) 是 Oracle 数据库的网络入口,接收并处理客户端连接请求[1]:

核心职责

  • 监听网络端口
  • 接收客户端连接
  • 转发连接到 Server Process
  • 维护服务注册信息

2. Listener 工作原理

2.1 连接建立流程

1. 客户端发起连接
   sqlplus scott/tiger@orcl
   
2. 客户端解析连接信息
   - 查找 tnsnames.ora / sqlnet.ora
   - 解析出主机、端口、服务名
   
3. TCP 三次握手
   - 客户端 → dbhost:1521
   
4. Listener 接收连接
   - 接收 TNS 数据包
   - 解析服务名
   
5. 服务查找
   - 在监听器服务列表中查找匹配服务
   - 找到则继续;未找到返回 ORA-12514
   
6. 进程派生(专用服务器)
   - Listener fork 一个 Server Process
   - Server Process 接管连接
   
7. 连接移交
   - Listener 将客户端连接转交给 Server Process
   - 后续通信不再经过 Listener
   
8. 客户端与 Server Process 直接通信

2.2 共享服务器模式

1-4. 同上
5. Listener 将请求放入 Request Queue
6. Shared Server Process 从 Queue 取请求处理
7. 处理结果放入 Response Queue
8. Dispatcher 将结果返回客户端

3. listener.ora 配置

3.1 基本配置

# $ORACLE_HOME/network/admin/listener.ora

# 监听器名称(默认 LISTENER)
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

# 日志/跟踪
LOGGING_LISTENER = ON
TRACE_LEVEL_LISTENER = OFF

3.2 多端口监听

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521)))
    (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1522)))
  )

3.3 多协议监听

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521)))
    (DESCRIPTION = (ADDRESS = (PROTOCOL = TCPS)(HOST = dbhost)(PORT = 2484)))
    (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)))
  )

3.4 静态注册

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = orcl)
      (ORACLE_HOME = /u01/app/oracle/product/19.3.0/dbhome_1)
      (SID_NAME = orcl)
    )
  )

4. 监听器管理

4.1 lsnrctl 命令

# 启动
lsnrctl start

# 停止
lsnrctl stop

# 状态
lsnrctl status

# 重启配置(不中断连接)
lsnrctl reload

# 服务列表
lsnrctl services

# 版本
lsnrctl version

4.2 启动多个监听器

# listener.ora
LISTENER1 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521)))
LISTENER2 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1522)))

# 启动指定监听器
lsnrctl start LISTENER1
lsnrctl start LISTENER2

5. 服务注册

5.1 动态注册

PMON 自动向监听器注册:

-- 数据库启动后 PMON 自动注册
-- 配置 LOCAL_LISTENER 指定非默认端口
ALTER SYSTEM SET local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=dbhost)(PORT=1522))' SCOPE=BOTH;

-- 强制注册
ALTER SYSTEM REGISTER;

5.2 静态注册

listener.ora 配置 SID_LIST_LISTENER

5.3 对比

维度动态注册静态注册
配置自动手动
维护
实例未启动时不显示显示
异常终止自动注销需手动维护
推荐仅特殊场景

详细内容见:Oracle 静态注册 vs 动态注册


6. 服务名与多服务

6.1 创建服务

-- 单实例
EXEC DBMS_SERVICE.CREATE_SERVICE(
  service_name => 'sales',
  network_name => 'sales'
);

-- 启动服务
EXEC DBMS_SERVICE.START_SERVICE('sales');

-- RAC 中通过 srvctl
srvctl add service -db orcl -service sales -preferred orcl1 -available orcl2

6.2 查看服务

-- 数据库服务
SELECT name, network_name, enabled 
FROM dba_services;

-- 监听器注册的服务
! lsnrctl services

7. 监听器日志

7.1 日志位置

$ORACLE_BASE/diag/tnslsnr/<host>/listener/alert/log.xml
$ORACLE_BASE/diag/tnslsnr/<host>/listener/trace/listener.log

7.2 日志内容

21-JUL-2026 10:23:15 * (CONNECT_DATA=(SERVICE_NAME=orcl)(CID=(PROGRAM=sqlplus)(HOST=client)(USER=scott))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.100)(PORT=54321)) * establish * orcl * 0
21-JUL-2026 10:23:16 * service_update * orcl * 0
21-JUL-2026 10:23:20 * service_died * orcl * 0

7.3 监控

# 实时监控
tail -f $ORACLE_BASE/diag/tnslsnr/dbhost/listener/trace/listener.log

# 统计连接
grep "establish" listener.log | wc -l

# 查找错误
grep -E "TNS-|ORA-" listener.log

8. RAC 中的监听器

8.1 SCAN Listener

RAC 12c+ 使用 SCAN(Single Client Access Name):

客户端 → SCAN (3 个 IP) → SCAN Listener → 节点 Listener → 实例
# SCAN 配置
srvctl config scan

# SCAN Listener
srvctl config scan_listener

8.2 节点本地 Listener

每个节点有自己的 Local Listener:

# 节点 Listener
srvctl config listener -n racnode1

# 配置
srvctl modify listener -listener LISTENER -endpoints TCP:1521

8.3 远程 Listener

ALTER SYSTEM SET remote_listener='rac-scan:1521' SCOPE=BOTH;
ALTER SYSTEM REGISTER;

9. 常见坑与排错

9.1 ORA-12541: TNS:no listener

修复

lsnrctl start
lsnrctl status

9.2 ORA-12514: TNS:listener does not currently know of service

修复

-- 1. 检查监听器服务
! lsnrctl services

-- 2. 强制注册
ALTER SYSTEM REGISTER;

-- 3. 检查 LOCAL_LISTENER
SHOW PARAMETER local_listener;

-- 4. 检查服务是否启动
SELECT name, enabled FROM dba_services;

9.3 ORA-12516: TNS:listener could not find available handler

现象:共享服务器模式连接数过多。

修复

-- 增大 SHARED_SERVERS
ALTER SYSTEM SET shared_servers=20 SCOPE=BOTH;
ALTER SYSTEM SET max_shared_servers=100 SCOPE=BOTH;

9.4 ORA-12520: TNS:listener could not find available handler

现象:专用服务器进程数过多。

修复

-- 增大 PROCESSES
ALTER SYSTEM SET processes=500 SCOPE=SPFILE;
-- 重启生效

9.5 监听器日志过大

修复

# 定期归档
cd $ORACLE_BASE/diag/tnslsnr/dbhost/listener/trace
mv listener.log listener.log.$(date +%Y%m%d)
lsnrctl reload  # 触发日志切换

10. 最佳实践

  1. 使用动态注册:自动维护
  2. LOCAL_LISTENER 显式配置:非默认端口必需
  3. 多监听器负载均衡:高并发场景
  4. 定期归档日志:避免文件过大
  5. 监控 listener 日志:发现连接问题
  6. RAC 用 SCAN:统一访问点
  7. 合理设置 PROCESSES:避免连接拒绝
  8. tnsping 测试:定期验证
  9. 加密传输:Native Encryption 或 SSL
  10. 网络配置统一:客户端与服务端 sqlnet.ora 一致

11. 参考资料

[1] Oracle Database Net Services Administrator’s Guide 19c, “Configuring and Administering Oracle Net Listener” https://docs.oracle.com/en/database/oracle/oracle-database/19/netag/configuring-and-administering-oracle-net-listener.html