目录
1.2.listener.ora和tnsnames.ora配置文件深度解析
二、listener.ora监听注册机制(静态注册与动态注册对比)
2.2.动态注册:自动感知,灵活高效(推荐,交给PMON进程来处理)
三、tnsname.ora配置(结合动态注册和静态注册来看)
[4.1 跟踪监听工作过程](#4.1 跟踪监听工作过程)
[3.2 巧用SSH端口转发实现安全连接](#3.2 巧用SSH端口转发实现安全连接)
[3.3 监听性能优化思路](#3.3 监听性能优化思路)
引言
Oracle监听(listener)**是客户端与数据库之间的"通信桥梁",是客户端连接数据库的必经之路。**尽管其维护逻辑相对简单,但"简单易被忽视"的特性导致它成为数据库连接故障的高频诱因。
日常运维中,"监听已启动但客户端无法连接""动态注册失败""连接缓慢"等问题屡见不鲜。
例如:

一、监听核心基础:连接原理与配置文件解析
一个监听可同时服务多个数据库实例,实例信息既可以通过listener.ora静态配置,也可由Oracle的PMON进程动态注册,极大提升了配置灵活性。
1.1.监听连接本质与核心组件
监听的核心作用是接收客户端连接请求并转发至数据库实例, 其工作流程遵循OSI模型的会话层规范。客户端通过TCP/IP三次握手与服务端建立连接,该过程仅涉及系统内核调用,响应速度较快。监听的核心配置文件包括三类:
1.1.1.listener.ora(服务端)
定义了监听器在哪里工作。 通常需要定义监听的协议、端口、服务名等核心参数,是监听运行的基础配置文件。
例如:
(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.100)(PORT=1521)),这表示监听器在 192.168.1.100 的 1521 端口等客户端来敲门。
1.1.2.tnsnames.ora(客户端常用)
提供了一个"地址本",告诉客户端应该去敲门(理解为映射表)。 用于存储数据库连接串信息,需与listener.ora配置**信息(协议、主机、端口、服务名)**保持一致。
例如:
ORCL =
(DESCRIPTION =
(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.100)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=orcl))
)
1.1.3.sqlnet.ora
可位于服务端或客户端,用于控制Oracle Net Services的行为,如会话跟踪、连接限制等。
1.1.4.工作原理
当客户端使用 sqlplus user/pwd@ORCL 命令时,它会从 tnsnames.ora 中找到名为 ORCL 的条目,获取 192.168.1.100:1521 和 服务名=orcl 这些信息,然后去连接服务端的监听器。只要这些信息匹配,连接就能成功,下面会进行详细的讲解。
1.2.listener.ora和tnsnames.ora配置文件深度解析
这两个文件是 Oracle 网络配置的核心。
1.2.1.lisener.ora
listener.ora是监听配置的核心,其格式固定且关键字敏感,以下从配置模板、关键字含义、常用命令三方面详细说明:
1)典型配置模板
bash
LISTENER=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(HOST=172.16.4.37)(PORT=1521))
)
)
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(GLOBAL_DBNAME=xe123)
(ORACLE_HOME=/var/oracle/ora10/product/10.2.0/db_1)
(SID_NAME=xe)
)
)
该模板分为两大模块:
LISTENER:定义监听的基础通信信息(协议、主机、端口);
SID_LIST_LISTENER:用于静态注册实例信息(服务名、Oracle主目录、实例名)。
2)核心关键字解析
PROTOCOL:指定监听支持的连接协议,常用TCP(默认),还支持IPC、SDP、加密TCP/IP等。例如,IPC协议配置为(PROTOCOL=ipc)(KEY=sales),适用于本地连接场景。
HOST:监听运行的主机标识,可配置为IP地址、主机名或IP解析名。若配置为主机名,监听将运行在服务器所有激活的网卡上;若配置为0.0.0.0,效果等同于主机名;配置为127.0.0.1则仅支持本地回环连接。
PORT:监听端口,默认1521。同一主机的不同IP可使用相同端口(需配合IP=FIRST参数),同一IP也可配置多个端口(如1521和1522),实现多监听分流。
GLOBAL_DBNAME:数据库服务名,静态注册时需与客户端tnsnames.ora的SERVICE_NAME一致,可与实例名不同。
SID_NAME:数据库实例名,需与数据库参数INSTANCE_NAME保持一致,是静态注册的核心参数。
ORACLE_HOME:实例对应的Oracle主目录,UNIX/Linux环境下默认与环境变量一致,Windows环境下取自注册表。
1.2.2.tnsnames.ora
为什么需要这个配置呢?
如果不配置 tnsnames.ora,我们就需要输入:EZCONNECT(Easy Connect) 格式的连接字符串。它不需要任何配置文件,只需在命令行直接输入以下格式:
sqlplus username/password@//host:port/service_name
正是因为这个原因,tnsnames.ora 这个配置文件它将用户容易记忆的网络服务名 (Net Service Name) 映射为包含数据库实际网络地址和连接信息的连接描述符 (Connect Descriptor):
仔细想想感觉它的作用类似于计算机中的域名与IP的关系。
sqlplus system/oracle@net_service_name
如下:

以下从配置模板、关键字含义方面详细说明:
1)典型配置模板
# 以这个为示例进行解读
# 连接别名(可自定义)
net_service_name =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = host_name)(PORT = port_number))
(CONNECT_DATA =
(SERVICE_NAME = service_name)
)
)
2)核心关键字解析
net_service_name (网络服务名):这是客户端用来连接的别名。 你**可以自由定义,**用户输入 sqlplus user/pass@net_service_name 即可连接,无需重复输入后面的长串信息。
**DESCRIPTION (描述):**这是一个容器,用于包含单个连接描述符(Connect Descriptor)。一个网络服务名下可以有多个 DESCRIPTION,以实现高级功能如故障转移。
**ADDRESS (地址):**用于指定数据库监听器(Listener)的网络位置,由协议、主机和端口组成:
**PROTOCOL:**通信协议,最常用的是 TCP。
**HOST:**数据库服务器的主机名或 IP 地址。
PORT: 监听器正在监听的端口号,默认是 1521。此地址必须与 listener.ora 中配置的地址匹配。
**CONNECT_DATA (连接数据):**指定要连接的数据库服务,这是最常用的参数:
**SERVER:**通常有两个选择,一个是DEDICATED(专用服务器-每一个客户端对应一个独立的服务器进程,资源占用多,性能好),一个是SHARED(共享服务器-多个客户端连接共享一组服务器进程,资源占用少,适合大量并发连接数高的场景)。
**SERVICE_NAME:**数据库的服务名。
**SID:**数据库的系统标识符,这是早期版本的用法,在一些老文档中常见。对于较新版本的 Oracle 数据库,通常推荐使用 SERVICE_NAME。
3)常用测试命令
tnsping orclpdb

1.3.监听管理常用命令
监听命令语法为:lsnrctl command listener_name(默认监听名可省略,但是若存在多个监听名,就必须进行指定)核心命令如下:
**启动监听:**lsnrctl start(RAC环境可通过lsnrctl start listener -n 节点名启动)
**关闭监听:**lsnrctl stop(不影响已经建立的客户端会话)
**查看状态:**lsnrctl status(显示监听版本、端口、注册服务、实例状态等)
**查看服务:**lsnrctl service(展示专用、共享服务器的连接负载、拒绝连接数等)
**重新装载配置:**lsnrctl reload(修订listener.ora后无需重启监听,执行此命令即可生效)
使用别名后,所有操作需指定别名,如lsnrctl start ALIAS、lsnrctl status ALIAS。
1.4.监听器中状态解读
|---------|-------------------------------|---------------------------------|
| 状态 | 含义 | 原因 |
| UNKNOWN | 监听器只知道有这个服务配置,但不知道实例是否真的启动并可用 | 该服务在listener.ora中通过SID_LIST静态配置 |
| READY | 实例已启动并向监听器动态注册,处于可用状态 | PMON进程自动注册,监听器能实时感知实例状态 |
| BLOCKED | 实例启动了,但当前无法接受新连接(如正在执行恢复) | 实例正在恢复或处于受限模式 |
二、listener.ora监听注册机制(静态注册与动态注册对比)
监听的实例注册分为静态注册和动态注册两种,二者适用场景不同,需根据业务需求选择配置:
在此之前我们先确认数据库的实例信息、服务名称:
bash
[oracle@single_oracle ~]$ ps -ef | grep pmon | grep -v grep
oracle 4476 1 0 11:33 ? 00:00:00 ora_pmon_orcl
[oracle@single_oracle ~]$
[oracle@single_oracle ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Thu Jun 4 13:58:14 2026
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL> select status from v$instance;
STATUS
------------
OPEN
SQL> -- 查看当前可插拔数据库信息
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCLPDB READ WRITE NO
SQL>
SQL>
SQL> set linesize 200
SQL> column name format a20
SQL> column network_name format a30
SQL> select name,network_name from dba_services order by name;
NAME NETWORK_NAME
-------------------- ------------------------------
SYS$BACKGROUND
SYS$USERS
p19c0 p19c0
p19c0XDB p19c0XDB
SQL>
结果:
|----------------|----------|
| 服务名 | 说明 |
| P19C0 | 主要数据库服务 |
| p19c0XDB | XML数据库服务 |
| SYSBACKGROUND | 后台进程专用服务 |
| SYSUSERS | 用户进程专用服务 |
|---------|--------------|
| 实例名 | 说明 |
| orcl | Oracle后台进程标识 |
2.1.静态注册:手动配置,强制绑定
静态注册是在listener.ora中明确指定实例信息,监听无需感知实例实际运行状态,即使实例未启动,具有sysdba权限的用户仍可通过监听连接进行维护。
核心配置要点
必须配置SID_NAME(实例名)、GLOBAL_DBNAME(服务名),ORACLE_HOME可省略(默认使用环境变量)。
oracle@single_oracle admin echo ORACLE_HOME
/u01/app/oracle/product/19c/dbhome_1
实例静态注册示例:
bash
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.75.155)(PORT = 1521))
)
)
# 对实例进行监听,这个在19c里边一般交给pmon进程来做,无需自己来操作(避免画蛇添足,这里只是为了测试)。
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
# 对CDB进行监听
(GLOBAL_DBNAME = P19C0)
(SID_NAME = orcl)
(ORACLE_HOME = /u01/app/oracle/product/19c/dbhome_1)
)
# 对CDB里边的PDB进行监听
(SID_DESC =
(GLOBAL_DBNAME = orclpdb)
(SID_NAME = orcl)
(ORACLE_HOME = /u01/app/oracle/product/19c/dbhome_1)
)
)
# 开启监听日志(方便排错)
LOGGING_LISTENER = ON
LOG_FILE_LISTENER = listener.log
LOG_DIRECTORY_LISTENER = /u01/app/oracle/diag/tnslsnr/single_oracle/listener/alert
结果:

2.2.动态注册:自动感知,灵活高效(推荐,交给PMON进程来处理)
动态注册无需在listener.ora中配置实例信息,实例启动时,PMON进程会自动将实例信息(服务名、实例名、负载情况)注册至监听;实例关闭时,PMON进程自动注销信息。动态注册要求实例至少处于nomount状态。
核心特性与配置:
注册内容:包括SERVICE_NAME(服务名,默认格式为DB_NAME.DB_DOMAIN)、INSTANCE_NAME(实例名)、实例负载、服务句柄(如专用服务器、调度器)等。
注册时间点:
实例后于监听启动时,nomount阶段完成注册。
实例先于监听启动时,监听启动后1分钟内(PMON进程定期扫描)自动注册。
执行alter system register命令手动触发注册。
修改SERVICE_NAME参数后自动触发注册。
实例状态:
动态注册的实例状态显示为READY(可接受连接)、BLOCKED(nomount状态或ASM实例,拒绝连接)、RESTRICTED(限制模式,仅允许特权用户连接)。
2.3.静态与动态注册的区别
| 特性 | 静态注册 | 动态注册 |
|---|---|---|
| 配置方式 | 手动编写listener.ora | PMON自动注册,无需配置 |
| 实例状态显示 | UNKNOWN | READY/BLOCKED/RESTRICTED |
| 实例未启动时连接 | 支持sysdba用户维护连接 | 无法连接 |
| 适用场景 | 实例启停频繁、需要远程维护 | 日常业务连接,追求灵活性 |
2.4.动态注册失败的排查思路
若实例无法动态注册至监听,可按以下步骤排查:
检查TNS_ADMIN环境变量是否正确设置(影响配置文件定位)。
验证/etc/hosts等域名解析文件,确保主机名与IP对应正确(可通过ping测试)。
检查LOCAL_LISTENER和REMOTE_LISTENER参数,建议直接配置为IP地址(避免域名解析问题)。
例如:
alter system set LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=172.16.4.37)(PORT=1521))';
尝试切换IPC协议注册(排除TCP协议配置错误):
alter system set LOCAL_LISTENER='(ADDRESS=(PROTOCOL=IPC)(KEY=KEY1))';
通过事件跟踪注册过程(设置事件10257),分析跟踪文件定位问题。
三、tnsname.ora配置(结合动态注册和静态注册来看)
tnsnames.ora 只是一个静态的文本配置文件,不存在像listener.ora"动态配置"的说法。它的作用只是做好该做好的映射关系:

3.1.静态监听配置
3.1.1.删除动态监听配置,解除冲突
bash
[oracle@single_oracle ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Thu Jun 4 15:45:30 2026
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL> show parameter listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
forward_listener string
listener_networks string
local_listener string (DESCRIPTION=(ADDRESS_LIST=(AD
DRESS=(PROTOCOL=TCP)(HOST=192.
168.75.155)(PORT=1521))))
remote_listener string
SQL>
SQL>
SQL> ALTER SYSTEM SET local_listener='' SCOPE=BOTH;
System altered.
SQL>
SQL> alter system register;
System altered.
SQL>
SQL> show parameter listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
forward_listener string
listener_networks string
local_listener string
remote_listener string
SQL>
SQL>
3.1.2.重载监听配置

可以发现监听配置里边的冲突已经解决了。
前面我们这个P19C0这个服务由于是静态注册,所以监听器一直在监听中,但是由于数据库不清楚映射关系,但是数据库中运行的服务所使用的实例却找不到。那接下来我们就需要做一下映射的配置。
这个配置通常放在$ORACLE_HOME/network/admin下边:
oracle@single_oracle admin$ pwd
/u01/app/oracle/product/19c/dbhome_1/network/admin
oracle@single_oracle admin echo ORACLE_HOME
/u01/app/oracle/product/19c/dbhome_1
oracle@single_oracle admin$
3.1.3.编辑tnsnames.ora
bash
[oracle@single_oracle admin]$ cat tnsnames.ora
ORCLPDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.75.155)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orclpdb)
)
)
[oracle@single_oracle admin]$
3.1.4.tns连通性测试

3.1.5.再次测试

可以看出这个已经是可以了。但是推荐还是把listener.ora里边的静态注册列表里边的所有配置删除。我们测试一下:
3.2.使用动态监听配置搭配tnsnames.ora
3.2.1.删除配置

3.2.2.加入动态配置
alter system set LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.75.155)(PORT=1521))';
alter system register;

3.2.3.重载监听器

可以看到19c这里直接使用pmon进程来动态注册监听其实更适配现实中的场景。再次测试前面的连接:
bash
[oracle@single_oracle ~]$ sqlplus test_04/oracle@orclpdb
SQL*Plus: Release 19.0.0.0.0 - Production on Thu Jun 4 16:02:22 2026
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Last Successful login time: Thu Jun 04 2026 15:54:25 +08:00
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL> show con_name;
CON_NAME
------------------------------
ORCLPDB
SQL>
SQL>
SQL> CREATE TABLE students (
id NUMBER(4) PRIMARY KEY,
name VARCHAR2(50),
age NUMBER(3),
city VARCHAR2(50)
); 2 3 4 5 6
Table created.
SQL>
结果也是一样的,推出,日常的管理中一般不对listener.ora配置做多余的修改,除非对于特殊要求场景。否则不需要进行配置,只需要配置tnsnames.ora即可。
四、监听实用技巧:跟踪、加密与性能优化
4.1 跟踪监听工作过程
监听响应缓慢时,可通过系统命令跟踪其工作流程(以HP-UX的tusc命令为例):
获取监听进程号:ps -ef | grep tnslsnr | grep -v grep(假设进程号为28297)。
启动跟踪:tusc -T hires -afpo lsnr.log 28297。
发起客户端连接,完成后按Ctrl+C停止跟踪。
分析跟踪文件lsnr.log,重点关注accept函数(串行处理连接,繁忙时会延迟)、进程派生(fork)等环节。
3.2 巧用SSH端口转发实现安全连接
默认情况下,客户端与数据库的通信数据为明文,广域网环境下存在安全风险。可通过SSH端口转发实现加密传输,配置步骤如下:
客户端执行转发命令(本地端口1555转发至服务端1521端口):
ssh -CNfg -L 1555:172.16.4.200:1521 ora10g@172.16.4.200
客户端tnsnames.ora配置连接串(指向本地转发端口):
gg11=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=172.16.4.28)(PORT=1555))
(CONNECT_DATA=
(SERVICE_NAME=gg11)
(SERVER=DEDICATED)
)
)
客户端通过sqlplus zhoul/zhoul@gg11连接,数据通过SSH加密通道传输。关闭转发:kill -9 转发进程号(通过ps -ef | grep CNfg获取进程号)。
3.3 监听性能优化思路
结合监听工作机制,从以下维度优化性能:
调整ARRAYSIZE参数:减少TCP包传输数量,根据TCP包大小(默认有效负载1460B)设置最优值(默认15行,可适当增大)。
增大SDU(会话数据单元):静态注册时,在listener.ora和tnsnames.ora中添加(SDU=4096);动态注册时,在sqlnet.ora中配置DEFAULT_SDU_SIZE=8192(Oracle 11.2后专用服务器默认8KB,共享服务器默认65KB)。
优化TCP缓冲区:调整操作系统参数(如AIX的tcp_sendspace、tcp_recvspace)和Oracle的SEND_BUF_SIZE、RECV_BUF_SIZE参数(广域网环境效果显著)。
增加监听并发能力:
设置QUEUESIZE参数(需配合操作系统队列参数,如HP-UX的tcp_conn_req_max),避免并发连接超限时出现ORA-12535错误。
配置多端口监听(如1521和1522),客户端根据负载选择连接。
减少短连接消耗:将客户端连接方式改为长连接或使用连接池,避免频繁建立/断开连接占用监听资源。
本地连接优先使用IPC协议:绕过监听处理环节,直接连接数据库(配置(PROTOCOL=ipc)(KEY=xxx))。
清理监听日志:过大的监听日志(如2GB以上)会导致连接缓慢,定期清理或设置日志轮转。
五、实战诊断案例:监听故障排查全流程(来源网络整理所得)
案例一:RAC节点宕机后的监听故障处理
RAC环境中1号节点宕机,VIP漂移至2号节点,但连接1号节点的客户端出现ORA-12541:TNS: no listener错误(客户端连接串固定指向1号节点IP)。
排查与解决
1.检查客户端连接串:zjsjjg1指向1号节点IP(130.37.8.41),SERVICE_NAME=zjsjjg。
2.验证2号节点IP:1号节点VIP(130.37.8.41)已漂移至2号节点,但2号节点监听仅配置监听rac2-vip(130.37.8.42),未监听漂移过来的VIP。
3.修改2号节点listener.ora:将HOST配置为主机名rac2,去掉IP=FIRST参数(监听所有网卡IP),并添加静态注册:
LISTENER_RAC2=
(DESCRIPTION_LIST=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST=rac2)(PORT=1521))
)
)
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC))
)
)
SID_LIST_LISTENER_RAC2=
(SID_LIST=
(SID_DESC=
(SID_NAME=zjsjjg2)
(ORACLE_HOME=/u01/oracle/product/10.2.0/db_1)
(GLOBAL_DBNAME=zjsjjg)
)
)
重启监听:lsnrctl reload LISTENER_RAC2,客户端无需修改连接串即可正常连接(VIP漂移+监听多IP监听)。
案例二:VPN环境下连接超时(ORA-12535)
客户端通过VPN连接数据库,ping 和tnsping 均正常(延迟800+ms),但sqlplus连接挂起,最终报错ORA-12525:TNS:operation timed out。
排查与解决
开启客户端sqlnet跟踪(sqlnet.ora中添加参数):
TRACE_LEVEL_CLIENT=16
TRACE_FILE_CLIENT=client_trace
TRACE_TIMESTAMP_CLIENT=ON
TRACE_DIRECTORY_CLIENT=D:\oracle\product\10.2.0\db_1\network\ADMIN
分析跟踪文件:发现传输1644字节数据时跟踪停止,推测VPN对数据包大小有限制。
验证数据包大小:执行ping 20.1.0.202 -t -l 1644,发现丢包率100%,确认VPN最大支持包长小于1644字节。
解决:应用厂商调整VPN包长限制,客户端连接恢复正常。
案例三:本地sqlplus连接HANG住背景
AIX系统中,NFS文件系统无法访问(与数据库无关),导致sqlplus / as sysdba连接HANG住,无响应。
排查与解决
使用truss命令跟踪连接过程:truss -D sqlplus '/as sysdba',发现跟踪停留在statx("./../nbu_nfs_102")(NFS文件系统路径),提示NFS server not responding。
原理:AIX系统中,sqlplus连接时会调用statx函数获取根目录下文件系统状态,若某文件系统无响应,会导致连接阻塞。
解决:强制卸载无响应的NFS文件系统:umount -f /nbu_nfs_102,连接恢复正常。
预防:避免将NFS文件系统挂载在根目录下,建议挂载至/nfs等独立目录。