Listener
Table of Contents
1 监听的作用
-
监听客户端请求
监听器运行在数据库服务器之上,与Oracle实例(可为多个)相关关联,是一个专门的进程process,在windows的服务项目或者Linux的运行进程列表中,都会看到对应的运行进程。Windows上名为TNSLSNR,Linux/Unix平台上是lsnrctl。监听器守候在服务器制定端口(默认为:1521),监听客户端的请求。
-
为客户端请求分配Server Process
监听器只负责接听请求,之后将请求转接给Oracle Server Process。在Oracle的服务模式下,客户端进程是不允许直接操作数据库实例和数据,而是通过一个服务进程Server Process(也称为影子进程)作为代理。监听器接受到请求之后,就向操作系统(或者Dispatcher组件)要求fork(或分配)一个Server Process与客户端相连。
-
注册实例服务
本质上将,listener是建立实例和客户端进程之间联系的桥梁。Listener与实例之间的联系,就是通过注册的过程来实现的。注册的过程就是实例告诉监听器,它的数据库数据库实例名称instance_name和服务名service_names。监听器注册上这样的信息,对客户端请求根据监听注册信息,找到正确的服务实例名称。目前Oracle版本中,提供动态注册和静态注册两种方式。
-
错误转移failover
Failover是RAC容错的一个重要方面功能,其功能是在数据库实例崩溃的时候,可以自动将请求转移到其他可用实例上的一种功能。可以提供很大程度上的可用性(Availability)功能。这个过程中,发现实例已经崩溃,并且将请求转移到其他实例上,就属于是listener的功能。
-
负载均衡
在RAC架构中,Oracle实现了负载均衡。当一个客户请求到来时,Oracle会根据当前RAC集群环境中所有实例的负载情况,避开负载较高的实例,将请求转移到负载较低的实例进行处理。在早期RAC版本中,负载轻重的衡量是根据监听器当前维护连接数目来确定的,而不是实时查看多实例的负载。RAC环境中的监听器之间进行沟通通信。~
2 静态监听与动态监听
- 动态监听,指的是Oracle 实例注册到监听服务的方式是动态的,是在实例启动的过程中, 或者启动后定时由进程将实例信息注册至监听进程的监听配置,实例停止,则监听服务不再监听该实例。
- 静态监听,指的是Oracle 实例注册至监听服务的方式是静态的,实例启动后,可手动从数据库发起注册命令,将实例注册至监听服务。 之后,监听服务则一直对该实例进行监听,与实例是否启动无关。
2.1 区别
远程连接 | |
动态监听 | 只有数据库启动时 |
静态监听 | 任何时间都可以连 |
-
连接
动态注册的监听,只有当数据库启动时,才可以远程连接。
静态注册的监听,无论数据库是否启动,都可以连接,也就是说,可以通过静态监听远程启动停止数据库,而动态监听不可以。
-
注册方式
动态监听,在Oracle 11G 及之前是通过pmon进行来进行注册的。Oracle 12C 之后,监听的注册由专有进程LREG 负责。
静态监听,需要手动注册,手动注册语句如下:
alter system register;
-
配置文件
动态的配置文件,在lsnrctl status中是不显示的。而在静态监听的配置中是显示的。
-
参数
动态监听最好配置local_listener ,而静态监听不需要配置。local_listener
-
实例信息获取
动态监听,是PMON进程根据参数文件中的service_names, instance_name 来进行注册的。
静态监听,是通过监听的参数文件中的配置取得service_name,ORACLE_HOME 等信息,再注册到监听的。
2.2 监听中的服务名和实例名
静态监听,一切基于配置文件。对于动态监听来讲,服务名和实例名是有一定识别规则的:
- 实例名
- 优先使用instance_name参数值,如果该参数没有设置,将使用db_name.
- 服务名
- 优先使用service_names参数值,如果没该参数有设置,将拼接db_unique_name和db_domain两个参数的值作为监听的service。
2.3 配置示例
2.3.1 静态监听
静态监听的信息是配置在listener.ora 这个参数文件中的。示例如下:
SID_LIST_LISTENER_FOREIGN = (SID_LIST = (SID_DESC = (SID_NAME = PLSExtProc) (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1) (PROGRAM = extproc) ) (SID_DESC = (SID_NAME = dbm012) (ORACLE_HOME = /u01/app/oracle/product/11.2.0.4/dbhome_1) (GLOBAL_DBNAME=dbm01) ) ) LISTENER_FOREIGN = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1)) (ADDRESS = (PROTOCOL = TCP)(HOST = 172.24.69.47)(PORT = 1521)) ) )
2.3.2 动态监听
动态监听,是不需要配置参数文件的,最多在数据库里配置local_listener 参数。示例如下:
alter system set LOCAL_LISTENER=‘(ADDRESS = (PROTOCOL = TCP)(HOST = xxx.xxx.xxx.xxx)(PORT = 1521))‘;
其实我们可以看到,local_listener 的值 ,就是tnsnames 中的一部分,我们也可以通过先配置tnsnemes.ora 文件,然后设置 local_listener=$tnsnames 即可。比如:
alter system set LOCAL_LISTENER=‘test_dg‘; -- test_dg 为tnsname.
3 密码
3.1 设置密码
设置密码需要通过lsnrctl 命令进入交互式,然后输入change_password 或者set password 来设置新的密码:
LSNRCTL> change_password Old password: New password: Reenter new password: Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ecp-uc-db1)(PORT=1521))) Password changed for LISTENER The command completed successfully LSNRCTL> set password Password: The command completed successfully LSNRCTL> save_config Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ecp-uc-db1)(PORT=1521))) Saved LISTENER configuration parameters.
- note
- 10G 数据库中,需要在参数文件中添加LOCAL_OS_AUTHENTICATION_LISTENER = OFF以关闭本地操作系统认证。
4 相关脚本
4.1 通过日志查看链接风暴
-
统计每分钟连接数
grep ‘13-APR-2014 19:[01-24]‘ ./listener.log.bak1 |awk ‘{print $1,$2,$6}‘|awk -F":" ‘{print $1,":",$2}‘|sort -n |uniq -c
-
统计每秒每个IP的连接数
egrep ‘13-APR-2014 12:[10-24]‘ ./listener.log |awk ‘{print $1,$2,$6}‘|awk ‘{print $2,$3}‘|awk -F‘(‘ ‘{print $1 $4}‘|tr -d ‘(ADDRESS=(PROTOCOL=tcp)(HOST=‘|sort -n |uniq -c
-
统计时间点上用户、进程连接数
egrep ‘13-APR-2014 12:18:36‘ ./listener.log.bak1 |awk -F "*" ‘{print $2}‘|awk -F‘(‘ ‘{print $6 $8}‘|sed ‘s/)/ /g‘|sort -n |uniq -c