Oracle 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 區別
遠程連接 | 信息來源 | 配置文件 | 參數 | |
動態監聽 | 只有數據庫啟動后 | 由PMON或者LREG根據實例參數文件中的service_name,instance_name動態注冊,實例未啟動,不監聽任何實例 | 不顯示配置文件 | local_listener |
靜態監聽 | 任何時間都可以連 | 根據監聽的配置獲取service_name,ORACLE_HOME信息,實例未啟動時同樣監聽該實例,只是狀態不是READY | 顯示配置文件 | 無 |
-
連接
動態注冊的監聽,只有當數據庫啟動時,才可以遠程連接。
靜態注冊的監聽,無論數據庫是否啟動,都可以連接,也就是說,可以通過靜態監聽遠程啟動停止數據庫,而動態監聽不可以。
-
注冊方式
動態監聽,在Oracle 11G 及之前是通過pmon進行來進行注冊的。Oracle 12C 之后,監聽的注冊由專有進程LREG 負責。
靜態監聽,需要手動注冊,手動注冊語句如下:
alter system register;
-
配置文件
動態的配置文件,在lsnrctl status中是不顯示的。而在靜態監聽的配置中是顯示的。
-
參數
動態監聽最好配置local_listener,而靜態監聽不需要配置。local_listener
-
實例信息獲取
動態監聽,是PMON進程根據參數文件中的service_names, instance_name 來進行注冊的。
靜態監聽,是通過監聽的參數文件中的配置取得service_name,ORACLE_HOME 等信息,再注冊到監聽的。
-
網絡
動態監聽, 只能注冊到默認監聽上,默認監聽的是TCP協議,1521端口。如果不想默認的方式注冊,則需要通過配置local_listener參數來實現。
靜態監聽, 可以根據需要進行配置,是使用TCP協議 還是UDP 協議 ,使用哪個端口.
2.2 監聽中的服務名和實例名
靜態監聽,一切基於配置文件。對於動態監聽來講,服務名和實例名是有一定識別規則的:
- 實例名
- 優先使用instance_name參數值,如果該參數沒有設置,將使用db_name.
- 服務名
- 優先使用service_names參數值,如果沒該參數有設置,將拼接db_unique_name和db_domain兩個參數的值作為監聽的service。
2.3 配置示例
2.3.1 靜態監聽
靜態監聽的信息是配置在listener.ora 這個參數文件中的。示例如下:
SID_LIST_LISTENER_halberd = (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=halberd1) ) ) LISTENER_FOREIGN = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1)) (ADDRESS = (PROTOCOL = TCP)(HOST = 172.29.30.13)(PORT = 1522)) ) )
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.
也可以直接設置ip:port/service_name 進行配置:
alter system set local_listener='xx.xx.xx.xx:1521/service_name';
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的連接數
- 10g/11G 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 - 12c 格式發生變化 egrep '13-APR-2014 12:[10-24]' ./listener.log |awk '{print $1,$2,$8}'|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
5 參數
5.1 remote_listener
該參數主要用於RAC環境中監聽器的遠程注冊,監聽器的遠程注冊主要用於實現負載均衡。
通常情況下,客戶端發出的連接請求會首先被LOCAL_LISTENER接收,然后由Master Instance來決定當前的連接請求應該由哪個目標Instance發出Server Process響應這個連接請求。在啟用了負載均衡的情形下,Master Instance會將請求轉發到負載較小的實例。如果此時Remote_Listener中指定的實例負載較小,那么當前的請求會被重定向到負載較小的Instance中來建立連接,派生服務器進程進行相應連接。
REMOTE_LISTENER參數在RAC環境下非常重要,是服務器實現負載均衡的一個工具。在服務器端的連接中,Oracle NET通過remote_listener確定當前RAC中的遠程監聽和實例,以便分發連接。
RAC環境中的監聽器可以分為本地監聽器和SCAN監聽器,分別對應LOCAL_LISTENER和REMOTE_LISTENER參數。
在RAC環境下不管是使用了默認的TCP和1521還是其他協議都建議配置LOCAL_LISTENER。
該參數,同時可以實現監聽與實例分離,就是監聽在一個節點上,而實例在另外一個節點上。
5.2 local_listener
本地監聽器對應的設置參數為LOCAL_LISTENER。這個參數控制着本地監聽器的注冊,因為本地監聽器的工作機制關系,通過本地監聽器的數據庫連接請求只會連接到本地節點的實例上。
RAC的每個節點上都會有獨立的本地監聽器,它會監聽該節點的Public IP和VIP,而每個節點的實例在啟動的時候也會向本地監聽器進行注冊,當然它也會向SCAN監聽器注冊,當VIP或者Public IP有連接請求的時候,本地監聽器就接受處理並和本地實例建立連接。如果某個節點故障,那么其上面的VIP會進行漂移,但本地監聽器並不會產生漂移。
6 scan listener
oracle11gR2 RAC開始引入scan概念,SCAN監聽器可以監聽到集群中運行的所有數據庫,它是實現SCAN負載均衡的原理所在。 一個RAC 支持1~3個SCAN 配置,可以配置域名也可以配置IP地址,如果使用IP地址,有幾個IP 配置就集群就會啟動幾個SCAN listener。 一般通過dns服務器或gns服務器解析scan,也可以使用/etc/hosts文件解析scan,只不過oracle官方不建議這樣做。
因為域名可配置為輪詢訪問IP,三個IP輪流使用。假如我們配置了3個ip供SCAN 使用,同時配置了DNS 解析,監聽配置中HOST的值是域名。 當其中一個IP故障不能使用時,dns 會自動解析下一個IP 地址。而且只有一個scan listener.
如果我們通過/etc/hosts ,配置3個IP地址,並為每個IP配置一個別名,集群啟動后就會有三個scan 監聽,當其實一個IP出現問題,無法使用時,對應的監聽將失去存在的意義 。
那么怎么解決這個問題呢: 使用客戶端TAF配置,來實現類似於DNS輪詢功能。
這里需要說明的是,有的人認為scan ip 只能是1個或者3個,這是不對的,scan ip 可以是1至3個。也就是說可以配置2個SCANIP. 而有人把Oracle的建議當作准則和金科玉律,不去嘗試,不去認知,不去了解內部真實的動作機制和原因,這樣的人,你的成長是有限的。 應對局面的能力也是有限的。
scan listener 實現的功能是路由轉發。將接收到的連接請求,轉發到壓力較小的節點的VIP上去。有研究的朋友,應該都知道, 每一個SCANIP,都對應着一個scan vip。這個SCAN VIP 就是各個節點上的VIP地址。而本地監聽監聽的地址包括VIP和publicIP. 當本地監聽中的VIP地址被請求時,本地監聽會進行認證和連接進程的建立。
為什么是轉發到VIP上呢? 因為 VIP會漂移呀,很帥呀,這個IP可以繼續支持業務訪問。一個節點掛了,VIP漂了,pulibc ip 死了。
Created: 2020-08-02 Sun 11:44