第十一章 配置网络环境
11.1 用户与Oracle数据库建立连接
网络服务(Net Service) - Oracle 使用网络服务从客户端或者中间层的应用服务器与数据库
服务器建立连接。
监听器 - 在客户端, 网络服务是作为后台运行的进程;在DB服务器端,网络服务通过名为
监听器的进程来体现。 还可以通过配置网络服务使异构数据库进行通信。
连接方式 - 两种:专用连接,共享连接
专用连接 - 这种方式下,服务器进程和用户进程一一对应,一旦用户进程中断,对应的服务
器进程也被终止。
-- 客户端段建立到服务器端的连接过程 :
A. 客户端发起连接,通过在客户端提供用户名,用户密码及连接字串(tnsnames.ora中设置),
建立与监听器的连接。
B. 客户端一旦与监听器建立了连接,则在客户端生成用户进程。同时监听器会判断客户端
请求的DB服务名是否为当前这个监听器管理的服务名(service_names), 如果不是或不存在,
报错且中断,如果是,则监听器会在该服务器名所在的DB服务器上创建服务器进程。
C. 监听器在创建服务器进程以后,会将用户进程和服务器进程建立连接,之后监听器退出与
客户端的连接(这就是为什么程序与DB建立连接后,即使关闭监听器,程序仍然连接着DB的原因)。
D. 服务器进程根据用户进程提供的用户名及密码到数据字典里判断是否匹配。
E. 如果不匹配,报错,如果匹配,则分配PGA, 并生成SESSION .
11.2 配置监听器
监听配置文件位于$ORACLE_HOME/network/admin/listener.ora,可以手工编辑,也可以通过
图形界面netca设置,1521 是监听器的默认端口。
典型的listener.ora 文件内容:
SID_LIST_LISTENER = (注册到监听器的service name所在区域)
(SID_LIST =
(SID_DESC = (对外部过程调用的服务名)
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/product/oracle)
(PROGRAM = extproc)
)
)
LISTENER = (监听名称)
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = franklindb)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0)) (对外部过程调用的监听信息)
)
)
-- 备注 --
默认安装时,会安装一个PL/SQL外部程序(ExtProc)条目在listener.ora中,
是oracle为调用外部程序默认配置的监听,它的名字通常是ExtProc或PLSExtProc,
但一般不会使用它。可以直接从listener.ora中将这项移除,因为对ExtProc已经有多
种攻击手段了,在不使用外部程序时,oracle也是建议删除的。
PLSExtProc是pl/sql external procdure的意思,就是在pl/sql中调用外部语句,
如c、java写的过程。现在,Oracle已经全面支持JAVA了,这东西也就过时了,之所以
继续保留是考虑到兼容以前老版本的数据库。
有时可能会在多个数据库实例之间拷贝listener.ora,检查拷贝来的文件中是否
含有不需要的服务,确保只留下的确需要的服务项目,减少监听器受攻击的面。
手工添加监听器 --
同一台server上可以存在多个监听器,只不过每个监听器必须在不同端口上进行监听,
这些监听器通过同一个listener.ora文件进行配置,比如添加一个my_listener监听:
MY_LISTENER = (监听名称)
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = franklindb)(PORT = 1526))
)
)
服务名称 --
监听器接收来自客户端的连接请求时,会判断客户端tnsnames.ora中设置请求的服务
名是否为该监听器管理的服务名,可是我们在listener.ora中没有发现服务名称的配置,
这是为什么呢 ?
这里我们先来了解服务名,可以把服务理解为一组相似任务的逻辑组合,比如一个企业
中的销售,采购,财务,人事等4个部门,那么可以划分4个服务名:sales,pur,fin,hr,
每个功能不同的部门连接到不同的服务名,这样可以对数据库活动分组,更好进行跟踪
和调优。
那么服务是如何体现在监听器里的呢 ? Oracle是通过将服务注册到监听器里来实现的。
有下面两种注册方式:
A. 动态注册 - 通过DB实例中的PMON将当前实例里的服务名(参数service_names)注册到
同一个服务器上的、默认的、并且是1521端口上监听的监听器,服务名由初始化参数
service_names 决定,该参数默认为数据库名,可以动态更改,也可以指定多个值,也
就是多个服务名,每个服务名之间通过逗号隔开。
SQL> alter system set service_names='ora10g,sales,pur,fin,hr' ;
修改后我们需要等一段时间,PMON进程就会将这些服务名都注册到默认的监听器中(默认
表示监听名称为LISTENER, 端口为1521), 当然,我们也可以不等PMON进程自动注册服务
名,而是执行下面的命令,理解将这些服务名注册到监听器中:
SQL> alter system register ;
备注: 一般我们在dbca建立数据库之前需要netca建立相关网络服务文件,然后dbca才会
动态注册,需要注意顺序 。
动态注册到非默认监听 --
如果需要将服务名动态注册到非默认监听,比如刚才建立的my_listener上,我们需要设置
实例初始化参数 local_listener . 该参数说明了要动态注册的监听器的信息。
SQL> alter system set local_listener=
'(ADDRESS_list=(ADDRESS = (PROTOCOL = TCP)(HOST = franklindb)(PORT = 1526)))' ;
这里应该也可以将这个host,ip等描述写入DB SERVER的tnsnames.ora中,设置别名来取代 ,比如 SQL> alter system set local_listener='tnsnames.ora中的别名' ;
详细介绍动态注册的文章:
http://space.itpub.net/35489/viewspace-622765
静态注册 --
相对与动态注册而言的,数据库服务名信息手工写入listener.ora 文件中。静态注册服务名
由SID_LIST_ 这部分来指定,例如:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/product/oracle)
(PROGRAM = extproc)
)
(SID_DESC = (添加这段SID_DESC,即可为默认监听静态注册一个服务名)
(GLOBAL_DBNAME = static_srv) (global_dbname表示对外公布的服务名)
(ORACLE_HOME = /u01/product/oracle)
(SID_NAME = ora10g)
)
)
备注: GLOBAL_DB_NAME 表示对外公布的服务名,也就是用户连接数据库时所使用
的名称,它可以任意取名 。SID_NAME 表示服务名对应的数据库实例名。我们可以
加入多个SID_DESC,从而为DB定义多个服务名 。
监听器的管理 --
$lsnrctl
LSNRCTL > help
LSNRCTL > start
LSNRCTL > start my_listener
LSNRCTL > stop
LSNRCTL > status
假设数据库实例名为teststby , 静态注册设置如下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/product/oracle)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME = teststby)
(ORACLE_HOME = /u01/product/oracle)
(GLOBAL_DBNAME = test11g2)
)
)
查看监听状态:
LSNRCTL > status
Service "PLSExtProc" has 1 instance(s).
Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "test11g2" has 1 instance(s).
Instance "teststby", status UNKNOWN, has 1 handler(s) for this service...
Service "teststby" has 1 instance(s).
Instance "teststby", status READY, has 1 handler(s) for this service...
Service "teststbyXDB" has 1 instance(s).
Instance "teststby", status READY, has 1 handler(s) for this service...
其中因为初始化参数中设置了 dispatchers='(PROTOCOL=TCP) (SERVICE=teststbyXDB)'
所以teststbyXDB状态也表现为READY, dispatchers 设置是用于共享服务器的。
其中teststby 是READY 状态,它就是初始化参数service_names中设置的服务名,而
Service "test11g2" 的status状态为UNKNOWN. 这是因为teststby 服务是在初始化
参数service_names中定义的(前面我们知道,可以定义多个服务名,逗号隔开),是
由PMON进程动态注册到监听器,因此PMON进程所在的数据库一定处于打开状态,所以
服务名对应的实例准备好(READY)接受用户连接请求。 但是test11g2 服务是通过
编辑listener.ora文件静态注册的服务名,监听器并不确定这个服务名对应的实例
是否有打开,所以实例对应的status为UNKNOWN .
备注: 动态注册的服务,在实例开启后,对应的监听自动开启,实例关闭后对应
的监听自动关闭 。
SQL> show parameter service
NAME TYPE VALUE
------------------------------------ ----------- ----------
service_names string teststby
关闭 teststby 实例后,READY对应的监听被自动关闭:
Service "PLSExtProc" has 1 instance(s).
Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "test11g2" has 1 instance(s).
Instance "teststby", status UNKNOWN, has 1 handler(s) for this service...
11.3 配置客户端
两种方式 : 简单连接及本地命名
sqlnet.ora 中设置ezconnect 表示简单连接,文件内容:
NAMES.DIRECTORY_PATH=(TNSNAMES,EZCONNECT)
简单连接方式: SQL> connect hr/hr@book.us.com:1521/ora10g
简单连接不支持负载均衡,故障转移(Failover)等高级特性 。
本地命名 - tnsnames.ora 位于客户端,例子:
TESTSTBY =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = dbtest)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = test11g2)
)
)
配置客户端的tnsnames.ora文件后,我们一般使用tnsping 来测试网络连接。
$ tnsping TESTSTBY (别名) , 能通,说明通过连接字串能连接到指定的监听
器上,但是该工具不会验证字串包含的服务名是否为监听器所管理的服务名,它
只是验证网络连接是否正常 。
11.4 配置共享连接
Oracle连接中有两种连接方式: 专用连接和共享连接 。
专用连接方式下用户进程和服务器进程一一对应,用户进程退出,服务器进程
也退出,并释放占用的资源,服务器进程作为用户进程的代理进程(影子进程),
负责执行用户进程发出的命令,并返回命令执行后得到的结果 。
共享连接方式下,用户进程和服务器进程存在多对多的关系,专用连接方式下,
建立连接后,用户进程没有命令发出时,服务器进程处于空闲状态,但是资源
仍然被占用(还是连接着),且不能处理其他用户进程发出的命令,但是在共享
连接中,只要某个服务器进程空闲,它还可以处理其他用户发出的命令,因此
需要的进程个数就减少了,资源的利用更加高效,占用的PGA也相对减少了。
因此可以支持更多的用户连接请求。
Dispatcher --
共享连接时,需要配置多个名为dispatcher的组件,它作为用户进程和服务器
进程之间的协调者,负责将用户进程的请求传递给服务器进程,并将服务器进程
得到的结果返回给用户,PMON进程会定期将每个dispatcher的地址及工作负载
注册到监听器,当用户进程连接到监听器时,监听器会选择一个负载最低的
dispatcher , 并把该dispatcher的地址返回给用户进程,从而用户进程与该
dispatcher建立起了连接。 用户进程在session的整个生命周期中,连接的
dispatcher是不会变化的。
共享连接模式下用户进程的连接过程如下:
A. 用户进程连接到监听器 ;
B. 监听器根据各个注册的dispatcher的负载,选择一个负载最低的dispatcher,
并将其地址返回给用户进程,假设监听器选择了dispatcher1 ;
C. 用户进程根据监听返回的地址,连接到该dispatcher ;
D. dispatcher接收到用户进程发出的请求后,会将请求放入请求队列,请求队列
位于SGA中,请求队列可以被所有dispatcher说共享;
E. 在服务器进程中,最空闲的服务器进程会从请求队列中按照先进先出的原则,
挑选一个请求进行处理;
F. 服务器进程将处理后的结果放入相应队列中(Oracle会为每个dispatcher准备
一个对应的响应队列)。
G. 响应队列中的结果返回给对应的dispatcher.
H. Dispatcher 将结果返回给用户进程。
PGA,UGA在两种连接模式下的分配 --
专用连接模式下,用户进程对应的PGA被服务器进程独享。
共享连接模式下,用户的PGA需要在不同的服务器进程之间共享,这时PGA中的UGA
(包括游标状态及session信息)会被转移到SGA中(为了共享),如果配置了large
pool, UGA在large pool中分配,如果没有,UGA在shared pool中分配。
配置共享连接 --
初始化参数 dispatchers = (PROTOCOL=TCP) (dispatchers=3) , 表示启动3个
dispatcher , 还可以通过设置max_dispatchers参数来定义最大可同时启动的
dispatcher数量 。比如max_dispatchers=10 .
服务器进程 -- 通过配置shared_servers 来配置服务器进程,可以动态生成 。
一般设置较少的数值,然后设置max_shared_servers 来限制同时运行的最大的
服务器进程 。 比如设置shared_servers=5,max_shared_servers=20,负载高
导致需要额外的服务器进程的时候,会自动创建服务器进程直到最多20个服务器
进程同时运行,当负载降低的时,会自动删除直到剩下5个服务器进程为止。
能够使用共享连接的session个数 --
shared_server_sessions 参数说明同时可以进行共享连接的session的个数 。
在服务器段配置共享连接后,还需要在客户端tnsnames.ora中指定共享连接方式
进行连接:
TESTSTBY =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = dbtest)(PORT = 1521))
(CONNECT_DATA =
(SERVER = shared)
(SERVICE_NAME = test11g2)
)
)
如果 (SERVER = DEDICATED) 表示为专用连接模式。
$ lsnrctl service 查看相关共享连接信息 。
共享连接的限制 --
有些操作是不能在共享连接的模式下进行的,包括开启关闭实例,创建表空间和
数据文件,维护表,索引等,这些动作必须在专用连接下进行。同时,共享连接
适用于纯OLTP应用,对于需扫描大量数据,运行较长时间的操作也不适合(因为共享
的服务器进程不能占用太久,数量较少),比如备份恢复等 。 所以一般共享连
接较少使用。
11.5 调用外部过程
在编写PL/SQL的过程中,有时候我们发现通过c或java等外部函数来实现会容易得多,
Oracle提供了在PL/SQL中调用外部函数(C函数或java class)的功能,扩展了PL/SQL
的程序功能。
调用外部函数的过程 :
A. 用户进程执行PL/SQL过程;
B. 执行过程各种,调用一个C++语言写的函数:c_func, 这里需要借助别名库(别名
库是数据库中的一个对象,用来描述一个外部函数所在的动态链接库的路径和名称,
通过别名库可以知道被调用的外部函数在哪个文件里) .
C. PL/SQL将对外部函数的调用请求发送给监听器。
D. 监听器生成一个extproc进程,该进程专门用来处理外部函数的调用,每个session
都会生成一个属于该session的extproc进程,并且在整个session生命周期里,extproc
进程会一直存在。
E. Extproc 进程复杂将别名库所指定的动态连接库文件加载到内存。
F. Extproc 进程执行指定的外部函数,并将结果返回给服务器进程,进而返回给用户进程。
监听及服务器端tnsnames.ora中配置extproc :
监听器中的extproc --
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/product/oracle)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME = teststby)
(ORACLE_HOME = /u01/product/oracle)
(GLOBAL_DBNAME = test11g2)
)
)
tnsnames.ora中的extproc设置 --
EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
)
(CONNECT_DATA =
(SID = PLSExtProc) -- 必须和监听中设置的SID一致
(PRESENTATION = RO)
)
)
-- 备注 --
默认安装时,会安装一个PL/SQL外部程序(ExtProc)条目在listener.ora中,
是oracle为调用外部程序默认配置的监听,它的名字通常是ExtProc或PLSExtProc,
但一般不会使用它。可以直接从listener.ora中将这项移除,因为对ExtProc已经有多
种攻击手段了,在不使用外部程序时,oracle也是建议删除的。
PLSExtProc是pl/sql external procdure的意思,就是在pl/sql中调用外部语句,
如c、java写的过程。现在,Oracle已经全面支持JAVA了,这东西也就过时了,之所以
继续保留是考虑到兼容以前老版本的数据库。
有时可能会在多个数据库实例之间拷贝listener.ora,检查拷贝来的文件中是否
含有不需要的服务,确保只留下的确需要的服务项目,减少监听器受攻击的面。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-673177/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/35489/viewspace-673177/
本文详细介绍了Oracle数据库网络配置方法,包括监听器与客户端配置、共享连接配置及外部过程调用等内容。解析了监听器的工作原理、服务注册机制以及客户端连接方式等关键技术点。
1747

被折叠的 条评论
为什么被折叠?



