應用程式範例實現基本故障監視器,以監視 DNS 資源 (in.named) 的可靠性。 故障監視器包含:
dns_probe,一個使用 nslookup 來驗證由資料服務範例控制的 DNS 資源是否正在執行的使用者定義的程式。 如果 DNS 未在執行,此方法將嘗試在本機重新啟動 DNS,或依據嘗試重新啟動的次數,要求 RGM 將資料服務重新置於其他節點。
dns_monitor_start,一個啟動 dns_probe 的回呼方法。 如果啟用了監視,RGM 將在資料服務範例上線之後自動呼叫 dns_monitor_start。
dns_monitor_stop,一個停止 dns_probe 的回呼方法。 RGM 將在資料服務範例離線之前自動呼叫 dns_monitor_stop。
dns_monitor_check,一個呼叫 Validate 方法的回呼方法,用於驗證在 PROBE 程式將資料服務故障轉移至新節點時配置目錄是否可用。
dns_probe 程式將實施一個連續的執行程序,該程序用來驗證由資料服務範例控制的 DNS 資源是否正在執行。 dns_probe 由 dns_monitor_start 方法來啟動,RGM 會在資料服務範例上線之後自動呼叫該方法。 資料服務由 dns_monitor_stop 方法來停止,RGM 會在資料服務範例離線之前呼叫該方法。
本節說明應用程式範例的 PROBE 方法之主要部分, 但未說明如為所有方法提供共用功能性中所描述的所有回呼方法的共用功能性,如 parse_args() 函式與獲取 syslog 工具。
如需 PROBE 方法的完整清單,請參閱PROBE 程式。
探測在無窮迴圈中執行。 它使用 nslookup 來驗證正確的 DNS 資源是否正在執行。 如果 DNS 正在執行,探測將在規定間隔 (由 Thorough_probe_interval 系統定義的屬性設定) 內休息,然後再進行檢查。 如果 DNS 未在執行,此程式將嘗試在本機重新啟動 DNS,或依據嘗試重新啟動的次數,要求 RGM 將資料服務重新置於其他節點。
Thorough_probe_interval – 設定探測休息的時間
Probe_timeout – 對執行探測作業的 nslookup 指令,實施探測的逾時值
Network_resources_used – 獲取 DNS 正在其上執行的 IP 位址
Retry_count 與 Retry_interval – 決定嘗試重新啟動的次數與透過其計算次數的時間間隔
Rt_basedir – 獲取包含 PROBE 程式和 gettime 公用程式的目錄
scha_resource_get() 函式將獲取這些屬性的值,並將這些值儲存於 shell 變數中,如下所示。
PROBE_INTERVAL=`scha_resource_get -O THOROUGH_PROBE_INTERVAL \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME` probe_timeout_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME Probe_timeout` PROBE_TIMEOUT=`echo $probe_timeout_info | awk '{print $2}'` DNS_HOST=`scha_resource_get -O NETWORK_RESOURCES_USED -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME` RETRY_COUNT=`scha_resource_get -O RETRY_COUNT -R $RESOURCE_NAME -G\ $RESOURCEGROUP_NAME` RETRY_INTERVAL=`scha_resource_get -O RETRY_INTERVAL -R $RESOURCE_NAME -G\ $RESOURCEGROUP_NAME` RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME -G\ $RESOURCEGROUP_NAME`
對於系統定義的屬性 (如 Thorough_probe_interval),scha_resource_get() 將僅傳回值。 對於延伸屬性 (如 Probe_timeout),scha_resource_get() 將傳回類型與值。 使用 awk 指令來僅獲取值。
探測本身是 nslookup 指令的一個無窮 while 迴圈。 在 while 迴圈之前,將會設定一個暫存檔以存放 nslookup 回覆。 probefail 和 retries 變數均初始化為 0。
# Set up a temporary file for the nslookup replies. DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe probefail=0 retries=0 |
設定探測的休息間隔
使用 hatimerun 啟動 nslookup ,傳送 Probe_timeout 值與識別目標主機
基於 nslookup 回覆碼的成功或失敗,設定 probefail 變數
如果 probefail 設定為 1 (失敗),將會確認對 nslookup 的回覆來自資料服務範例而非其他 DNS 伺服器
以下是 while 迴圈碼。
while : do # The interval at which the probe needs to run is specified in the # property THOROUGH_PROBE_INTERVAL. Therefore, set the probe to sleep # for a duration of THOROUGH_PROBE_INTERVAL. sleep $PROBE_INTERVAL # Run an nslookup command of the IP address on which DNS is serving. hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST \ > $DNSPROBEFILE 2>&1 retcode=$? if [ $retcode -ne 0 ]; then probefail=1 fi # Make sure that the reply to nslookup comes from the HA-DNS # server and not from another nameserver mentioned in the # /etc/resolv.conf file. if [ $probefail -eq 0 ]; then # Get the name of the server that replied to the nslookup query. SERVER=` awk ' $1=="Server:" { print $2 }' \ $DNSPROBEFILE | awk -F. ' { print $1 } ' ` if [ -z "$SERVER" ]; then probefail=1 else if [ $SERVER != $DNS_HOST ]; then probefail=1 fi fi fi |
probefail 變數是除了 0 (成功) 以外的某個值,意味著 nslookup 指令逾時或回覆來自範例服務的 DNS 之外的伺服器。 在其中任何一種情況下,DNS 伺服器都不會發揮預期的功能,而故障監視器會呼叫 decide_restart_or_failover() 函式,以決定是在本機重新啟動資料服務還是要求 RGM 將資料服務重新置於其他節點。 如果 probefail 變數為 0,則會產生一條探測成功的訊息。
if [ $probefail -ne 0 ]; then decide_restart_or_failover else logger -p ${SYSLOG_FACILITY}.err\ -t [$SYSLOG_TAG]\ "${ARGV0} Probe for resource HA-DNS successful" fi |
decide_restart_or_failover() 函式使用時間視窗 (Retry_interval) 與失敗計數 (Retry_count) 來決定是在本機重新啟動 DNS 還是要求 RGM 將資料服務重新置於其他節點。 該函式實施以下條件式程式碼 (請參閱PROBE 程式中 decide_restart_or_failover() 的程式碼清單)。
如果是第一次失敗,請重新啟動資料服務。 記錄錯誤訊息並按 retries 變數中的計數器。
如果這不是第一次失敗,但已超出視窗,則請重新啟動資料服務。 記錄錯誤訊息、重設計數器並滑動視窗。
如果時間仍在視窗內,但已超出重試計數器,則故障轉移至其他節點。 如果故障轉移未成功,請記錄錯誤訊息並以狀態 1 (失敗) 結束探測程式。
如果時間仍在視窗內,且尚未超出重試計數器,則請重新啟動資料服務。 記錄錯誤訊息並按 retries 變數中的計數器。
如果重新啟動的次數達到了時間間隔內的限制次數,函式將要求 RGM 將資料服務重新置於其他節點。 如果重新啟動的次數在限制範圍之內,或已超出間隔從而計數器重新開始計數,函式將嘗試重新啟動相同節點上的 DNS。 請注意以下有關此函式的資訊:
gettime 公用程式用於追蹤重新啟動之間的時間。 這是常駐在 (Rt_basedir) 目錄中的 C 程式。
系統定義的資源屬性 Retry_count 與 Retry_interval 將決定嘗試重新啟動的次數以及透過其計數的間隔。 儘管叢集管理員可以變更設定,但這些 RTR 檔案中的屬性將預設為在 5 分鐘 (300 秒) 的間隔內嘗試重新啟動 2 次。
將呼叫 restart_service() 函式,以嘗試重新啟動相同節點上的資料服務。 請參閱下一節 (重新啟動資料服務),以取得有關此函式的資訊。
透過 GIVEOVER 選項,scha_control() API 函式使包含資料服務範例的資源群組離線,並在其他節點上重新上線。
restart_service() 函式將由 decide_restart_or_failover() 呼叫,以嘗試重新啟動同一節點上的資料服務。 此函式將執行以下作業。
此函式決定是否仍在 PMF 下註冊資料服務。 如果仍註冊服務,函式將:
獲取 Stop 方法名稱與資料服務的 Stop_timeout 值。
使用 hatimerun 啟動資料服務的 Stop 方法,傳送 Stop_timeout 值。
(如果資料服務成功停止) 獲取資料服務的 Start 方法名稱和 Start_timeout 值。
使用 hatimerun 啟動資料服務的 Start 方法,並傳送 Start_timeout 值。
如果已不再在 PMF 下註冊資料服務,意味著資料服務已超出在 PMF 下允許重試的最大次數,因此將使用 GIVEOVER 選項來呼叫 scha_control() 函式,以將資料服務故障轉移至其他節點。
function restart_service { # To restart the data service, first verify that the # data service itself is still registered under PMF. pmfadm -q $PMF_TAG if [[ $? -eq 0 ]]; then # Since the TAG for the data service is still registered under # PMF, first stop the data service and start it back up again. # Obtain the Stop method name and the STOP_TIMEOUT value for # this resource. STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM? STOP_METHOD=`scha_resource_get -O STOP \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM? hatimerun -t $STOP_TIMEOUT $RT_BASEDIR/$STOP_METHOD \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME if [[ $? -ne 0 ]]; then logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \ “${ARGV0} Stop method failed.” return 1 fi # Obtain the START method name and the START_TIMEOUT value for # this resource. START_TIMEOUT=`scha_resource_get -O START_TIMEOUT \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM? START_METHOD=`scha_resource_get -O START \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM? hatimerun -t $START_TIMEOUT $RT_BASEDIR/$START_METHOD \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME if [[ $? -ne 0 ]]; then logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \ “${ARGV0} Start method failed.” return 1 fi else # The absence of the TAG for the dataservice # implies that the data service has already # exceeded the maximum retries allowed under PMF. # Therefore, do not attempt to restart the # data service again, but try to failover # to another node in the cluster. scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \ -R $RESOURCE_NAME fi return 0 } |
如果嘗試本機重新啟動失敗並且嘗試將故障轉移至其他節點亦失敗,則資料服務範例的 PROBE 程式將以失敗狀態結束。 該程式將會記錄訊息「故障轉移嘗試失敗」。
在資料服務範例上線之後,RGM 將呼叫 Monitor_start 方法來啟動 dns_probe 方法。
本節說明應用程式範例的 Monitor_start 方法之主要部分, 但未說明如為所有方法提供共用功能性中所描述的所有回呼方法的共用功能性,如 parse_args() 函式與獲取 syslog 工具。
如需 Monitor_start 方法的完整清單,請參閱Monitor_start 方法。
該方法將使用程序監視器工具 (pmfadm) 來啟動探測。
Monitor_start 方法將獲取 Rt_basedir 屬性的值以建構 PROBE 程式的完整路徑名稱。 該方法將使用無限重試選項 pmfadm (-n -1, -t -1) 來啟動探測,此選項意味著如果探測無法啟動,PMF 將在無限時間內嘗試無限次數來啟動探測。
# Find where the probe program resides by obtaining the value of the # RT_BASEDIR property of the resource. RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME` # Start the probe for the data service under PMF. Use the infinite retries # option to start the probe. Pass the resource name, type, and group to the # probe program. pmfadm -c $RESOURCE_NAME.monitor -n -1 -t -1 \ $RT_BASEDIR/dns_probe -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME |
當資料服務範例離線時,RGM 將呼叫 Monitor_stop 方法來停止 dns_probe 的執行。
本節說明應用程式範例的 Monitor_stop 方法之主要部分, 但未說明如為所有方法提供共用功能性中所描述的所有回呼方法的共用功能性,如 parse_args() 函式與獲取 syslog 工具。
如需 Monitor_stop 方法的完整清單,請參閱Monitor_stop 方法。
該方法使用程序監視器工具 (pmfadm) 查看探測是否正在執行,如果是,則停止探測。
Monitor_stop 方法使用 pmfadm -q 查看探測是否正在執行,如果是,則使用 pmfadm -s 來停止探測。 如果探測已停止,則該方法無論如何會以成功狀態結束,這樣會保證該方法的等冪性。
# See if the monitor is running, and if so, kill it. if pmfadm -q $PMF_TAG; then pmfadm -s $PMF_TAG KILL if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Could not stop monitor for resource " \ $RESOURCE_NAME exit 1 else # could successfully stop the monitor. Log a message. logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Monitor for resource " $RESOURCE_NAME \ " successfully stopped" fi fi exit 0 |
確定搭配 pmfadm 使用 KILL 訊號與而不是遮罩訊號 (如 TERM) 來停止探測。 否則,Monitor_stop 方法可能無限期地掛起並最終逾時。 出現此問題的原因是,當有必要重新啟動資料服務或故障轉移資料服務時,PROBE 方法呼叫 scha_control()。 當 scha_control() 呼叫 Monitor_stop 作為使資料服務離線程序的一部分時,如果 Monitor_stop 使用遮罩訊號,它會掛起等待 scha_control() 完成,scha_control() 會掛起等待 Monitor_stop 完成。
如果 Monitor_stop 方法無法停止 PROBE 方法,則前者會記錄一條錯誤訊息。 RGM 會在主要節點上將資料服務範例置於 MONITOR_FAILED 狀態,這樣可能會使該節點發生混亂。
Monitor_stop 應該在停止探測之後結束。
每當 PROBE 方法嘗試將包含資料服務的資源群組故障轉移至新節點時,RGM 均將呼叫 Monitor_check 方法。
本節說明應用程式範例的 Monitor_check 方法之主要部分, 但未說明如為所有方法提供共用功能性中所描述的所有回呼方法的共用功能性,如 parse_args() 函式與獲取 syslog 工具。
如需 Monitor_check 方法的完整清單,請參閱Monitor_check 方法。
必須實現 Monitor_check 方法,以免與同時執行的其他方法發生衝突。
Monitor_check 方法將呼叫 Validate 方法以驗證 DNS 配置目錄在新節點上是否可用。 Confdir 延伸屬性指向 DNS 配置目錄。 因此,Monitor_check 將獲取 Validate 方法的路徑與名稱以及 Confdir 的值。 它將傳送此值至 Validate,如以下清單所示。
# Obtain the full path for the Validate method from # the RT_BASEDIR property of the resource type. RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAM? # Obtain the name of the Validate method for this resource. VALIDATE_METHOD=`scha_resource_get -O VALIDATE \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM? # Obtain the value of the Confdir property in order to start the # data service. Use the resource name and the resource group entered to # obtain the Confdir value set at the time of adding the resource. config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME Confdir` # scha_resource_get returns the type as well as the value for extension # properties. Use awk to get only the value of the extension property. CONFIG_DIR=`echo $config_info | awk `{print $2}'` # Call the validate method so that the dataservice can be failed over # successfully to the new node. $RT_BASEDIR/$VALIDATE_METHOD -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME -x Confdir=$CONFIG_DIR |
請參閱Validate 方法,以查看應用程式範例如何確認節點扥管資料服務的適合性。