Oracle Net Services支持从客户端应用到Oracle数据库服务器的网络会话。建立会话之后,Oracle Net将充当客户端应用和数据库服务器之间的数据信使。它负责建立和维护客户端应用和数据库服务器之间的连接,以及在它们之间传输消息。
在客户端,Oracle Net是负责应用连接到数据库的一个后台组件;在服务端,则会有一个Oracle Net监听器(Listener)进程,负责协调数据库和应用之间的连接。
可以通过Oracle Net Manager配置Oracle Net服务的以下组件:
组件 | 描述 | 配置文件 |
---|---|---|
Listeners | 服务端进程,负责监听客户端发来的数据库连接请求,并对连接流量进行管理 | listener.ora |
Naming methods | 客户端应用尝试连接到数据库服务时使用的解析方法,用于将连接标识符(connect identifier)解析为连接描述符(connect descriptor) | |
Naming (net service name) | 服务的连接标识符,被解析为连接描述符后可以用于识别网络位置和服务 | tnsnames.ora(本地配置) |
Profiles | 参数的集合,用于描述在客户端和服务端使用和配置Oracle Net特性的偏好 | sqlnet.ora |
listener.ora
一般位于grid用户的$ORACLE_HOME/network/admin/
目录下,tnsnames.ora
、sqlnet.ora
一般位于oracle用户的$ORACLE_HOME/network/admin/
目录下。
Oracle Net Listener可以理解为是所有非本地用户连接到数据库实例的网关(gateway)。一个监听器可以为多个数据库实例、以及成千上万个客户端连接提供服务。
在创建Oracle数据库的过程中,Oracle Net Configuration Assistant工具会创建一个名为LISTENER的本地监听器。该监听器会监听下面的TCP/IP协议地址:
(ADDRESS=(PROTOCOL=tcp)(HOST=host_name)(PORT=1521))
注册是指将数据库作为一个服务注册到监听器。客户端和数据库服务器建立连接时,监听器通过已注册的服务名监听客户端的连接。启动数据库时,默认有两条信息注册到监听器中,分别为数据库服务器对应的实例和服务。通过对外提供的服务名,客户端不需要知道数据库名和实例名,只需知道该数据库对应的服务名就可以实现对数据库的连接。该服务名可能与实例名相同,也可以不相同。
静态注册是指通过解析listener.ora
配置文件来注册数据库实例和服务。采用静态注册时,listener.ora
的内容通常形似下面:
LISTENER_ORCLDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = ORCLDB-vip)(PORT = 1521))
)
SID_LIST_LISTENER_ORCLDB =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = ORCL)
(ORACLE_HOME = /oracle/product/11.2.0)
(SID_NAME = ORCL)
)
)
其中:
LISTENER
模块一般包含监听器名字(LISTENER_ORCLDB)、连接协议(TCP)、监听主机(ORCLDB-vip)、监听端口等配置信息。SID_LIST_LISTENER
模块一般包含数据库服务名(GLOBAL_DBNAME)、ORACLE_HOME目录、数据库实例名(SID_NAME)等配置信息。静态注册模式下,监听器不知道实例的具体状态,所以执行lsnrctl status
查看监听的实例状态时,会显示status UNKNOWN
。
动态注册则是通过数据库服务端的PMON进程(Process MONitor)来动态地注册。采用动态注册时,无需手动配置listener.ora
文件。实例启动时,Oracle PMON进程会将数据库实例信息动态注册到监听器上;当Oracle实例关闭时,会PMON进程自动从监听里撤销当前实例信息。
动态注册模式下,执行lsnrctl status
查看监听的实例状态时,可能会有三种情况:
READY
:表示数据库实例已经处于Mount或者Open状态,可以接受客户端连接;BLOCKED
:表示数据库实例无法接收客户端连接;RESTRICTED
:表示实例处于RESTRICED模式,不接受普通权限的远程客户端连接。如果客户端应用想通过监听器连接到数据库服务,首先它需要知道监听器所在的主机地址、监听器接受的协议、以及监听的端口等信息。最后,应用还需要知道它想要连接到的数据库服务的名称。
应用用户通过向数据库实例发送一个连接字符串来发起连接请求。连接字符串通常包含用户名、密码、连接标识符(connect identifier)等信息,如下所示:
CONNECT jsmith/jspass@finflowers
上面用到的连接标识符是一个名为finflowers
的网络服务名(Net service name)。
连接标识符可以通过服务名解析方法(Naming methods)被解析为下面的连接描述符(connect desriptor):
finflowers=(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=flowers-server)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=finance.us.flowers.com)))
Oracle Net支持下面三种服务名解析方法:
tnsnames.ora
;下面主要介绍前两种方法。
Easy connect naming
此种方法允许客户端使用一个TCP/IP连接字符串来连接到数据库实例。连接字符串中必须包含主机名,可选端口、以及服务名。如下所示:
SQL> connect username/password@host[:port][/service_name]
Local naming
Local naming的好处在于用户可以使用一个简短的别名而不是一整串连接字符串。Oracle Net会检查这些别名并转化为主机地址、连接协议、端口、服务名称等信息。
Local naming方法使用的配置文件是tnsnames.ora
,其内容大致如下。
配置示例1
sample1=
(DESCRIPTION=
(SOURCE_ROUTE=yes)
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(HOST=host1)(PORT=1630)) # 1
(ADDRESS_LIST=
(FAILOVER=on)
(LOAD_BALANCE=off) # 2
(ADDRESS=(PROTOCOL=tcp)(HOST=host2a)(PORT=1630))
(ADDRESS=(PROTOCOL=tcp)(HOST=host2b)(PORT=1630)))
(ADDRESS=(PROTOCOL=tcp)(HOST=host3)(PORT=1521))) # 3
(CONNECT_DATA=(SERVICE_NAME=sales.us.example.com)))
根据上面的配置
(ADDRESS=(PROTOCOL=tcp)(HOST=host1)(PORT=1630))
(ADDRESS_LIST=
(FAILOVER=on)
(LOAD_BALANCE=off)
(ADDRESS=(PROTOCOL=tcp)(HOST=host2a)(PORT=1630))
(ADDRESS=(PROTOCOL=tcp)(HOST=host2b)(PORT=1630)))
(ADDRESS=(PROTOCOL=tcp)(HOST=host3)(PORT=1521))
配置示例2
下面是另一种配置:
ORCLSALES=
(DESCRIPTION=
(LOAD_BALANCE=on)
(FAILOVER=on)
(ADDRESS_LIST=
(SOURCE_ROUTE=yes)
(ADDRESS=(PROTOCOL=tcp)(HOST=host1)(PORT=1630))
(ADDRESS=(PROTOCOL=tcp)(HOST=host2)(PORT=1521))
)
(ADDRESS_LIST=
(SOURCE_ROUTE=yes)
(ADDRESS=(PROTOCOL=tcp)(HOST=host3)(port=1630))
(ADDRESS=(PROTOCOL=tcp)(HOST=host4)(port=1521))
)
(CONNECT_DATA=
(SERVER=DEDICATED)
(SERVICE_NAME=ORCLSALES)
)
)
上面的配置中开启了LOAD_BALANCE和LOAD_BALANCE,客户端连接请求会被随机转发到其中一个ADDRESS_LIST。如果这个ADDRESS_LIST挂了,应用连接就会通过故障转移被转发到另一个ADDRESS_LIST。
References
【1】记录一份Oracle 正确的监听配置文件listener.ora与tnsnames.ora
【2】Oracle监听的静态注册和动态注册
【3】Oracle 数据库Listener动态注册和静态注册
【4】Oracle Net Listener
【5】Local naming parameters