暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

实战 LOCAL_LISTENER, REMOTE_LISTENER, LISTENER_NETWORKS 的配置

ByteHouse 2024-07-14
1239

摘要:

对于 LOCAL_LISTENER, REMOTE_LISTENER, LISTENER_NETWORKS 与 RAC CLIENT-SIDE TAF 和 LOAD BALCANING 的 使用我之前也是一知半解,在日常的使用中慢慢理解。再次做个总结,因为部分内容自己经过了测试,但是没有整理出完整的文档来。希望日后能完善。
部分内容来自网络,望大家指点。

local_listener

LOCAL_LISTENER specifies a network name that resolves to an address or address list of Oracle Net local listeners (that is, listeners that are running on the same machine as
this instance). The address or address list is specified in the TNSNAMES.ORA file or other address repository as configured for your system.

当oracle的本地监听为非默认情况时,会用到local_listener参数。

什么是注册

注册就是将数据库作为一个服务注册到监听程序。客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库。这个服务名可能与实例名一样,也有可能不一样。

在数据库服务器启动过程中,数据库服务器会向监听程序注册相应的服务(无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务。)

在数据库服务器和客户端之间有一监听程序(Listener),在监听程序中,会记录相应数据库对应的服务名(一个数据库可能对应有多个服务名),当客户端需要连接数据库时,只需要提供服务名,就可以建立客户端和服务器之间的连接。

动态注册

动态注册是在instance启动的时候PMON进程根据init.ora中 instance_name,service_names两个参数将实例和服务动态注册到listener中。

SQL> set linesize 1000
SQL> show parameter name

NAME				     TYPE		    VALUE
------------------------------------ ---------------------- ------------------------------
cell_offloadgroup_name		     string
db_file_name_convert		       string
db_name 			               string		    big
db_unique_name			         string		    big
global_names			           boolean		   FALSE
instance_name			          string		    big
lock_name_space 		           string
log_file_name_convert		      string
processor_group_name		       string
service_names			          string		    big
SQL> 

首先要在init.ora中指定instance_name,service_names两个参数的值。

注册到监听器中的实例值从init.ora文件中的instance_name参数取得。

  • 如果该参数没有设定值,那么它将取init.ora文件中的db_name的值。

  • 如果在RAC中配置,您必须将集群中每个实例的instance_name参数设置为一个唯一的值。

注册到监听器中的服务值从init.ora文件中的参数service_names取得。

  • 如果该参数没有设定值,数据库将拼接init.ora文件中的 db_name和db_domain的值来注册自己。

  • 如果选择提供service_names值,您可以使用完全限定的名称(比如 orcl.oracle.com)或缩写的名称(比如orcl)。

  • 如果选择缩写的名称并设置了db_domain参数,注册到监听器中的服务将是 service_name值和db_domain值的拼接。

    例如下面的设置将导致服务orcl.oracle.com被注册到监听器中:

    db_domain=oracle.com
    service_names=orcl ;

采取动态注册方法时,listener.ora中的内容如下:

SID_LIST_LISTENER =  
  (SID_LIST =    
    (SID_DESC =    
      (SID_NAME = PLSExtProc)    
      (ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1)    
      (PROGRAM = extproc)    
    )    
  )

LISTENER =  
  (DESCRIPTION_LIST =    
    (DESCRIPTION =    
      (ADDRESS = (PROTOCOL = TCP)(HOST = big)(PORT = 1521))    
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))    
    )    
  )

可选择的是,您可以在service_names参数中指定多个服务值,值之间用逗号格开,这对于共享服务器配置是很有用的。

动态注册默认只注册到默认的监听器上(名称是LISTENER、端口是1521、协议是TCP),因为pmon只会动态注册port等于1521的监听,否则pmon不能动态注册listener,如果需要向非默认监听注册非默认的端,则需要配置local_listener参数。

将监听的信息添加到 tnsnames.ora 文件中, pmon在动态注册监听时要从tnsnames.ora中读取相关信息。

BIG = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.20.17)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = dmms) ) )

然后以sys用戶运行:

SQL> alter system set local_listener=BIG; SQL> alter system register; 或者: SQL> alter system set LOCAL_LISTENER='(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.20.17)(PORT = 1521))'; SQL> alter system register; $lsnrctl status listener

如果没有显式设置service_names和instance_name的值,那么仅当数据库在监听器运行之后启动时,动态注册才会发生;在这种情况下,如果监听器后来发生了重启,动态注册信息将会丢失。显然,最好在所有的数据库启动之前先启动监听器,这样就会避免没有显式设置 service_names和instance_name的值时,若重启监听器带来的动态注册信息丢失的情况。

为初始化参数service_names和instance_name设置显式的值是个很好的实践,尽管如果您没有设置它们,Oracle也会为动态注册而生成默认值(基于db_name和db_main)。这样做的原因是,如果监听器在数据库启动之后重新启动,其动态注册行为将会有一些微妙的区别。如果监听器在数据库运行之后重新启动,你们仅当您在init.ora文件中显式地设置了service_names和instance_name的值时,每个数据库的PMON进程才会在很短的时间之后自动注册数据库。

如果需要执行连接时故障转移或负载均衡,或者想要在RAC中配置在实例之间透明地分布连接,那么使用service_names参数将是必要的。为启用这些功能,您只需要将每个实例的数据库参数文件中的service_names设置为同一个值,并在客户端连接请求的service_name设置中引用该值。

如果没有显式设置service_names和instance_name的值,那么仅当数据库在监听器运行之后启动时,动态注册才会发生;在这种情况下,如果监听器后来发生了重启,动态注册信息将会丢失。显然,最后在启动任何数据库之前启动服务器上的监听器,并完全避免监听器的重启。

另外,您还可以在SQL*PLUS中使用命令:

SQL> ALTER SYSTEM REGISTER;

在数据库打开时的任何时候,手工地在监听器中注册服务值。这个命令对于替换因监听器重启而丢失地服务值很有用,并且它所注册地值与在数据库启动时由动态注册所设置的值完全一样。

静态注册

静态注册就是实例启动时读取listener.ora文件的配置,将实例和服务注册到监听程序。无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务。

静态注册时,listener.ora中的GLOBAL_DBNAME向外提供服务名,listener.ora中的SID_NAME提供注册的实例名。采取静态注册方法时,listener.ora中的内容如下:

SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME= big) (SID_NAME = big) (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1) ) )

该文件表明数据库是单实例的,实例名为orcl,向外提供了两个服务:orcl和orcl1

其中global_dbname对应的是oracle对外的服务名,即初始化参数里的service_names

而sid_name对应的是oralce实例的名称,即初始化参数里的instance_name

既然有动态监听为什么还要静态监听呢?原因如下:

1.监听器不是最早启动,oracle实例先启动

2.监听器重启

3.oracle实例没有open

查询某服务是静态注册还是动态注册

可以使用命令lsnrctl status来查看某服务是静态注册还是动态注册。

实例状态为UNKNOWN值时表明此服务是静态注册的设置。这时监听器用来表明它不知道关于该实例的任何信息,只有当客户发出连接请求时,它才检查该实例是否存在。

动态注册的数据库通过状态信息中的状态READY或状态BLOCKED(对于一个备用数据库)来指明。不管关闭何时数据库,动态注册的数据库都会动态地从监听器注销,而与之相关的信息将从状态列表中消失。这样,不管数据库是在运行还是已经关闭,监听器总是知道它的状态。该信息将被用于连接请求的回退(fallback)和负载平衡。

配置 local_listener

local_listener参数有两种书写格式,提供了不同的功能。

[root@localhost dmms]# cat /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora # listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora # Generated by Oracle configuration tools. LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.20.17)(PORT = 1521)) ) ) SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME=dmms) (SID_NAME = dmms) (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1) ) ) BIG_TEST = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.20.17)(PORT = 1521)) ) ) ADR_BASE_LISTENER = /u01/app/oracle [root@localhost dmms]# [root@localhost dmms]# cat /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/tnsnames.ora # Generated by Oracle configuration tools. BIG = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.20.17)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = BIG) ) ) BIG_TEST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.20.17)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = BIG) ) ) [root@localhost dmms]#
  1. 使用 IP地址和端口
alter system set LOCAL_LISTENER='(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.20.17)(PORT = 1521))';
  1. 使用别名解析
    在tnsnames.ora文件中写出network_name描述的监听信息,如上面的big
alter system set local_listener=BIG_TEST;

验证:
有数据库的动态注册(READY)了。

remote_listener

REMOTE_LISTENER specifies a network name that resolves to an address or address list of Oracle Net remote listeners (that is, listeners that are not running on the same machine as this instance). The address or address list is specified in theTNSNAMES.ORA file or other address repository as configured for your system.

当监听和实例本身不在同一台服务器上时,remote_listener参数就会起作用了。

192.168.20.30 为数据库服务器,没有配监听。编辑tnsnames.ora和设置remote_listener参数:

[oracle@test1 admin]$ cat tnsnames.ora DMMS = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.20.17)(PORT = 1522)) ) [oracle@test1 admin]$ sqlplus / as sysdba SQL> alter system set remote_listener=DMMS; System altered. SQL> exit

192.168.20.17为单独的监听服务器:

$ lsnrctl status DMMS

在192.168.20.31上客户端登陆测试:

$ tnsping dmms

这种数据库实例和监听不在同一台机器上的情况并不多见。

listerner_networks

在RAC中,每个节点的LOCAL_LISTENER参数必须指定本节点的vip,remote_listener必须指向scanIP。

当rac加入额外的监听时,一般会设置此参数。

根据用户需求,为Oracle 19C RAC 添加第二个网络,并配置监听
http://bytesystem.online/doc/2711/

当新的1522监听建立后,是没有任何服务注册进来的。这时就需要设置listener_networks参数了:

配置ORACLE RAC 支持多网络

SQL> show parameter listener_networks

NAME                     TYPE     VALUE
------------------------------------ ----------- ------------------------------
listener_networks             string
SQL>
SQL> show parameter local_listener

NAME                     TYPE     VALUE
------------------------------------ ----------- ------------------------------
local_listener                 string      (ADDRESS=(PROTOCOL=TCP)(HOST=
                         73.12.130.17)(PORT=1521))
SQL>

SQL> show parameter remote_listener

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------
remote_listener string zxrdsrv:1521

修改配置

# 节点1
ALTER SYSTEM SET listener_networks=
'((NAME=network1)(LOCAL_LISTENER=10.46.61.201:1521)(REMOTE_LISTENER=10.46.61.203:1521))',
'((NAME=network2)(LOCAL_LISTENER=10.47.61.201:1522)(REMOTE_LISTENER=10.47.61.202:1522))' 
SCOPE=BOTH SID='zxrdsrv1';

# 节点2
ALTER SYSTEM SET listener_networks=
'((NAME=network1)(LOCAL_LISTENER=10.46.61.202:1521)(REMOTE_LISTENER=10.46.61.203:1521))',
'((NAME=network2)(LOCAL_LISTENER=10.47.61.202:1522)(REMOTE_LISTENER=10.47.61.201:1522))' 
SCOPE=BOTH SID='zxrdsrv2';

新建立的LISTENER2也有了相应的注册信息

此时看监听的状态,已经有新的服务自动注册进来了,这时,新的网段的vip就能对外提供监听服务了。

RAC 环境下 local_listener与remote_listener

在RAC中,每个节点的LOCAL_LISTENER参数必须指定本节点的vip,remote_listener必须指向scanIP。

在 安装完RAC以后, oracle会自动修改local_listener和remote_listener这两个参数,同时把两个节点的3要素添加到$ORACLE_HOME/network/admin下的tnsnames.ora文件中:

LOCAL_LISTENER, REMOTE_LISTENER 与RAC CLIENT-SIDE TAF 和 LOAD BALCANING

Oracle RAC 同时具备HA(High Availiablity) 和LB(LoadBalance), 而其高可用性的基础就是Failover(故障转移)。它指集群中任何一个节点的故障都不会影响用户的使用,连接到故障节点的用户会被自动转移到健康节点,从用户感受而言, 是感觉不到这种切换。

Oracle 10g RAC 的Failover 可以分为3种:

  1. Client-Side Connect time Failover

  2. TAF

  3. Service-Side TAF

不能在listener.ora 文件中设置GLOBAL_NAME, 因为这个参数会禁用 Connect-time Failover 和 Transparent Application Failover.

Client-Side Connect Time Failover

如果用户端tnsname 中配置了多个地址,用户发起连接请求时,会先尝试连接地址表中的第一个地址,如果这个连接尝试失败,则继续尝试使用第二个地址,直至连接成功或者遍历了所有的地址。

这种Failover的特点:只在建立连接那一时刻起作用,也就是说,这种Failover方式只在发起连接时才会去感知节点故障,如果节点没有反应,则自动尝试地址列表中的下一个地址。一旦连接建立之后,节点出现故障都不会做处理,从客户端的表现就是会话断开了,用户程序必须重新建立连接。

启用这种Failover的方法就是在客户端的tnsnames.ora中添加FAILOVER=ON 条目,这个参数默认就是ON,所以即使不添加这个条目,客户端也会获得这种Failover能力。

对RAC的Failover做了分类:Service-SideTAF是在服务器上配置的,Client-Side TAF是在客户端配置的。

当客户端发出连接请求给Server端listener的时候,通过local_listener注册的服务接收这个连接请求,然后由master instance来决定这个连接请求应该由哪个目标instance发出server
process响应这个连接请求。如果启用负载均衡,那么主节点会选择cpu负载最小的那个instance,此时:

  • 如果master分配的目标instance是local listener machine,那么直接通过local server listener,开启后台的server process,处理发出conn的客户端,建立连接,处理会话;

  • 如果master分配的目标instance不是local listener machine,那么会通过remote_listener这个参数,把连接请求转移到remote machine上的listener;

    然后由remote service listener发出一个server process返回客户端,建立连接,处理会话.

当conn建立连接以后,listener就没有用了,不会再用到了,如果这个时候,已经连接的那个instance down了,会重新由新分配的master instance通过remote_listener切换到可用instance,此时客户不会发现连接中断。conn 和 select操作是不会中断的。

当实例1注册监听的时候,即使节点2的instance没有启动,也会通过remote_listener在节点2 server上注册相应的listener1。它是在数据库启动的时候,添加到相应的listener service里的。

TAF(Transparent Application Failover)

该配置参考:10g & 11g Configuration of TAF(Transparent Application Failover) and Load Balancing [ID 453293.1]

现在的大部分流行的应用系统(如:weblogic, Jboss),都是启动时就建立若干到数据库的长连接,在应用程序整个生命周期内重用这些连接。 而Client-Side Connet Time Failover的工作方式是它对应用程序的可用性没有太大帮助。

所以从Oracle 8.1.5 版本只有引入了新的Failover 机制—TAF。 所谓TAF,就是连接建立以后,应用系统运行过程中,如果某个实例发生故障,连接到这个实例上的用户会被自动迁移到其他的健康实例上。对于应用程序而言,这个迁移过程是透明的,不需要用户的介入,当然,这种透明要是有引导的,因为用户的未提交事务会回滚。 相对与Client-Side Connect Time Failover的用户程序中断,抛出连接错误,用户必须重启应用程序,TAF 这种方式在提高HA上有了很大的进步。

TAF 的配置也很简单,只需要在客户端的tnsnames.ora中添加FAILOVER_MODE配置项。这个条目有4个子项目需要定义。

  1. METHOD: 用户定义何时创建到其实例的连接,有BASIC 和 PRECONNECT 两种可选值。
  • BASIC: 是指在感知到节点故障时才创建到其他实例的连接。

  • PRECONNECT: 是在最初建立连接时就同时建立到所有实例的连接,当发生故障时,立刻就可以切换到其他链路上。

两种方法比较: BASIC方式在Failover时会有时间延迟,PRECONNECT方式虽然没有时间延迟,但是建立多个冗余连接会消耗更多资源,两者就是是用时间换资源和用资源换时间的区别。

  1. TYPE: 用于定义发生故障时对完成的SQL 语句如何处理,其中有2种类型:session 和select.

这2种方式对于未提交的事务都会自动回滚,区别在于对 select 语句的处理,对于select,用户正在执行的select语句会被转移到新的实例上,在新的节点上继续返回后续结果集,而已经返回的记录集则抛弃。

假设用户正在节点1上执行查询,整个结果集共有100条记录,现在已从节点1上返回10条记录,这时节点1宕机,用户连接被转移到节点2上,如果是session模式,则需要重新执行查询语句;如果是select方式,会从节点2上继续返回剩下的90天记录,而已经从节点1返回的10条记录不会重复返回给用户,对于用户而言,感受不到这种切换。

显然为了实现 select 方式,Oracle 必须为每个session保存更多的内容,包括游标,用户上下文等,需要更多的资源也是用资源换时间的方案。

  1. DELAY 和 RETRIES: 这2个参数分别代表重试间隔时间和重试次数。

Service-Side TAF

Service-Side TAF的配置参考: How To Configure Server Side Transparent Application Failover [ID 460982.1]

Service-SideTAF 可以看作是TAF的一种变种,首先Service-SideTAF也是TAF,所有TAF的特点它都有,其次这种TAF是在服务器上配置的,而不像TAF是在客户端配置的。

Client-Side TAF 是在客户端修改tnsnames.ora 文件来配置的,如果有很多客户端使用这个数据库,那么每次微笑调整都需要把所有的计算机更改一遍,既低效又容易出错。而Service-Side TAF 通过结合Service,在数据库里保存FAIL_MODE的配置,把所有的TAF配置保存在数据字典中,从而省去了客户端的配置工作,客户端的TNS文件就不需要任何TAF的配置选项了。

从配置参数而言,Service-Side TAF和TAF 相比多了一个Instance Role(实例角色)的概念。 所谓的实例角色,就是当有多个Instance 参与一个Service时,可以配置优先使用哪一个Instance为用户提供服务。用户共有两种可选角色。

  • PREFERRED:首选实例,会优先选择拥有这个角色的实例提供服务。

  • AVAILABLE: 后备实例,用户连接会优先连接PREFFERRED的Instance,当PREFERRED的Instance不可用时,才会被转到AVAILBALE的Instance上。

要使用Server-Side TAF必须配置Service。 Service 可以在创建数据库时创建,也可以在创建数据库之后修改,既可以使用dbca 配置向导,也可以用命令行的 方式配置。

最后修改时间:2024-07-15 14:52:03
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论