Oracle Net Services 架构

Oracle Net Services 架构

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


1. 概述

Oracle Net Services 是 Oracle 的网络通信框架[1],负责客户端与数据库实例之间的连接管理:

核心组件

组件作用
Listener(监听器)接收客户端连接
Oracle Net通信协议层
Naming Methods名称解析
Oracle Connection Manager高级连接管理
Shared Server / DRCP连接复用

2. 通信架构

+-----------+        +-----------+        +-----------+
|  Client   | <----> |  Listener | <----> |  Server   |
|  (SQL*Plus|        |           |        |  Process  |
|   JDBC)   |        |           |        |           |
+-----------+        +-----------+        +-----------+

协议层:
+-----------+        +-----------+        +-----------+
| Client    |        | Server    |        | Server    |
| Oracle    | <----> | Oracle    | <----> | Process   |
| Net       |  TNS   | Net       |  IPC   |           |
+-----------+        +-----------+        +-----------+

支持的协议:
- TCP/IP(最常用)
- TCP/IP with SSL
- Named Pipes(Windows)
- SDP(InfiniBand)
- IPC(本地进程间通信)

3. Listener 监听器

3.1 监听器配置

# $ORACLE_HOME/network/admin/listener.ora
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

# 多端口监听
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521)))
    (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1522)))
  )

3.2 启动与停止

# 启动
lsnrctl start

# 停止
lsnrctl stop

# 状态
lsnrctl status

# 重启
lsnrctl reload

3.3 监听器状态

lsnrctl status

# 输出示例:
# Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dbhost)(PORT=1521)))
# STATUS of the LISTENER
# -----------------------
# Alias                     LISTENER
# Version                   TNSLSNR for Linux: Version 19.0.0.0.0
# Start Date                21-JUL-2026 10:23:15
# Uptime                    5 days 4 hr. 12 min. 23 sec
# Trace Level               off
# Security                  ON: Local OS Authentication
# SNMP                      OFF
# Listener Parameter File   /u01/app/oracle/product/19.3.0/dbhome_1/network/admin/listener.ora
# Listener Log File         /u01/app/oracle/diag/tnslsnr/dbhost/listener/alert/log.xml
# Listening Endpoints Summary...
#   (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=dbhost)(PORT=1521)))
#   (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
# Services Summary...
# Service "orcl" has 1 instance(s).
#   Instance "orcl", status READY, has 1 handler(s) for this service...
# The command completed successfully

4. 客户端配置

4.1 tnsnames.ora

# $ORACLE_HOME/network/admin/tnsnames.ora
ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )

# RAC 配置(多地址)
ORCL_RAC =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
    (LOAD_BALANCE = ON)
    (FAILOVER = ON)
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
      (FAILOVER_MODE =
        (TYPE = SELECT)
        (METHOD = BASIC)
        (RETRIES = 3)
        (DELAY = 5)
      )
    )
  )

4.2 sqlnet.ora

# $ORACLE_HOME/network/admin/sqlnet.ora
# 名称解析顺序
NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT, LDAP)

# 默认域名
NAMES.DEFAULT_DOMAIN = example.com

# 认证方式
SQLNET.AUTHENTICATION_SERVICES = (NTS)

# 连接超时(秒)
SQLNET.INBOUND_CONNECT_TIMEOUT = 60

# 加密
SQLNET.ENCRYPTION_SERVER = REQUIRED
SQLNET.ENCRYPTION_TYPES_SERVER = (AES256, AES192, AES128)

4.3 Easy Connect

无需 tnsnames.ora 配置:

# 简单格式
sqlplus scott/tiger@dbhost:1521/orcl

# 含实例名
sqlplus scott/tiger@dbhost:1521/orcl/sales

# 含参数
sqlplus scott/tiger@dbhost:1521/orcl?connect_timeout=60

5. 命名方法

5.1 支持的命名方法

方法说明
Local Naming(tnsnames.ora)本地文件,最常用
Directory Naming(LDAP)集中目录,企业级
Easy Connect简单格式
External Naming(NIS)外部命名服务
Host Naming仅主机名

5.2 配置命名方法

# sqlnet.ora
NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT, LDAP)

详细内容见:Oracle 命名方法详解


6. 服务注册

6.1 动态注册(推荐)

PMON 进程自动将实例信息注册到监听器:

-- 启用动态注册
ALTER SYSTEM SET local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=dbhost)(PORT=1521))' SCOPE=BOTH;

-- 强制注册
ALTER SYSTEM REGISTER;

6.2 静态注册

listener.ora 中手动配置:

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

详细对比见:Oracle 静态注册 vs 动态注册


7. 连接流程

7.1 专用服务器连接

1. 客户端发起连接:sqlplus scott/tiger@orcl
2. 客户端解析 tnsnames.ora,获取 dbhost:1521/orcl
3. 客户端 TCP 连接到 dbhost:1521
4. Listener 接收连接
5. Listener fork 一个 Server Process(专用服务器模式)
6. Listener 将客户端连接转交给 Server Process
7. 客户端直接与 Server Process 通信
8. Server Process 处理 SQL 请求

7.2 共享服务器连接

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

8. Connection Manager(CMAN)

8.1 作用

  • 多路复用(Multiplexing)
  • 访问控制(防火墙)
  • 协议转换

8.2 配置

# cman.ora
CMAN =
  (ADDRESS=(PROTOCOL=TCP)(HOST=cman_host)(PORT=1630))

CMAN_PROFILE =
  (PARAMETER_LIST=
    (ASO_AUTHENTICATION=OFF)
    (AUTHENTICATION_LEVEL=0)
    (MAXIMUM_RELAYS=128)
    (LOG_LEVEL=1)
    (TRACING=NO)
    (RELAY_STATISTICS=NO)
    (SHOW_TNS_INFO=NO)
    (USE_ASYNC_CALL=NO)
    (REMOTE_ADMIN=FALSE)
  )

CMAN_RULES =
  (RULE_LIST=
    (RULE=(SRC=dbclient)(DST=dbserver)(SRV=orcl)(ACT=accept))
  )

9. 网络加密

9.1 Native Encryption

# sqlnet.ora
SQLNET.ENCRYPTION_SERVER = REQUIRED
SQLNET.ENCRYPTION_TYPES_SERVER = (AES256, AES192, AES128)
SQLNET.CRYPTO_CHECKSUM_SERVER = REQUIRED
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA256, SHA1)

9.2 SSL/TLS

# sqlnet.ora
SQLNET.AUTHENTICATION_SERVICES = (TCPS)
SSL_CLIENT_AUTHENTICATION = TRUE
SSL_CIPHER_SUITES = (SSL_RSA_WITH_AES_256_CBC_SHA)

# listener.ora
LISTENER =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCPS)(HOST = dbhost)(PORT = 2484))
  )

详细内容见:Oracle 网络加密与 SSL/TLS


10. 监控与诊断

10.1 Listener 日志

# 监控 listener 日志
tail -f $ORACLE_BASE/diag/tnslsnr/dbhost/listener/alert/log.xml

# 文本格式
tail -f $ORACLE_BASE/diag/tnslsnr/dbhost/listener/trace/listener.log

10.2 相关视图

-- 监听器信息
SELECT * FROM v$listener_network;

-- 连接信息
SELECT 
  sid, 
  serial#, 
  username, 
  machine, 
  program, 
  service_name
FROM v$session
WHERE type <> 'BACKGROUND';

-- 服务信息
SELECT name, network_name, creation_date 
FROM dba_services;

10.3 tnsping 测试

# 测试连接
tnsping orcl

# 输出:
# TNS Ping Utility for Linux: Version 19.0.0.0.0
# Used parameter files:
# /u01/app/oracle/product/19.3.0/dbhome_1/network/admin/sqlnet.ora
# Used TNSNAMES adapter to resolve the alias
# Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orcl)))
# OK (10 msec)

11. 常见坑与排错

11.1 ORA-12541: TNS:no listener

现象:客户端连接报 ORA-12541。

修复

# 1. 检查监听器状态
lsnrctl status

# 2. 启动监听器
lsnrctl start

# 3. 检查端口
netstat -tln | grep 1521

# 4. 检查防火墙
firewall-cmd --list-ports

11.2 ORA-12154: TNS:could not resolve the connect identifier

现象:找不到服务名。

修复

# 1. 检查 tnsnames.ora
cat $ORACLE_HOME/network/admin/tnsnames.ora | grep orcl

# 2. 检查 TNS_ADMIN 环境变量
echo $TNS_ADMIN

# 3. 测试 tnsping
tnsping orcl

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

现象:监听器不识别服务。

修复

# 1. 检查监听器注册的服务
lsnrctl services

# 2. 强制注册
sqlplus / as sysdba
ALTER SYSTEM REGISTER;

# 3. 检查 LOCAL_LISTENER
SHOW PARAMETER local_listener;

11.4 ORA-12560: TNS:protocol adapter error

现象:协议错误。

修复

# 检查 ORACLE_SID
echo $ORACLE_SID

# 检查 listener.ora 协议配置
cat $ORACLE_HOME/network/admin/listener.ora

12. 最佳实践

  1. 生产用动态注册:自动维护
  2. 多监听器分散负载:多端口监听
  3. 启用网络加密:保护数据传输
  4. RAC 使用 SCAN:统一访问点
  5. 监控 listener 日志:发现连接问题
  6. tnsnames.ora 集中管理:避免配置分散
  7. 设置连接超时:防止资源耗尽
  8. 使用 LDAP 集中管理:大型企业
  9. 网络加密:Native Encryption 或 SSL
  10. CMAN 用于高级场景:防火墙、多路复用

13. 参考资料

[1] Oracle Database Net Services Administrator’s Guide 19c https://docs.oracle.com/en/database/oracle/oracle-database/19/netag/

[2] Oracle Database Net Services Reference 19c https://docs.oracle.com/en/database/oracle/oracle-database/19/netrf/