使用 DSDL 的資源類型實作通常具有擔負下列職責的故障監視器常駐程式。
定期監視被管理的應用程式的運作狀況。 監視器常駐程式的這個特定方面嚴格相依於應用程式,並隨資源類型的不同而有很大不同。 DSDL 具有某些內建公用程式函式,以執行基於 TCP 的簡單服務運作狀況檢查。 執行基於 ASCII 的協定的應用程式 (例如 HTTP、NNTP、IMAP 和 POP3) 可以使用這些公用程式來實施。
由使用資源屬性 Retry_interval 和 Retry_count 的應用程式記錄遇到的問題。 在應用程式完全失敗時,決定 PMF 動作程序檔是否應該重新啟動服務,或應用程式失敗是否已經累積得如此迅速,以至於可能需要考慮故障轉移。 DSDL 公用程式 scds_fm_action() 和 scds_fm_sleep() 預定會幫助您實施此機制。
採取適當的動作 (通常重新啟動應用程式或嘗試對所包含的資源群組進行故障轉移)。 DSDL 公用程式 scds_fm_action() 實施此類演算法。 為達到此目的,它計算在過去的 Retry_interval 秒內,探測失敗的目前累積量。
更新資源狀態,以便 scstat 指令與叢集管理 GUI 可以使用應用程式運作狀態。
設計了 DSDL 公用程式,從而故障監視器常駐程式的主迴圈便可以由下列虛擬程式碼來表示。
對於使用 DSDL 來實施的故障監視器,
由於透過 PMF 的程序失敗通知非同步,因此透過 scds_fm_sleep() 偵測應用程式程序失敗非常迅速。 與故障監視器不時喚醒以檢查服務運作狀況並尋找失敗應用程式的情況進行對比。 故障偵測時間明顯減少,因此服務可用性增加。
如果 RGM 拒絕透過 scha_control(3HA) API 轉移服務故障的嘗試,則 scds_fm_action() 重設 (遺忘) 其目前的失敗歷史。 原因是失敗歷史已經超出 Retry_count,如果監視器常駐程式在下一次重覆中喚醒且無法成功完成其常駐程式的運作狀況檢查,它將再次嘗試呼叫 scha_control() 呼叫,但可能仍會被拒絕,因為在上一次重覆中導致其被拒絕的情形仍然存在。 重設歷史將確保故障監視器至少嘗試在下一個重覆中在本機校正此情形 (例如,透過應用程式重新啟動)。
一旦重新啟動失敗,scds_fm_action() 將不重設應用程式失敗歷史,因為如果此情形未自行校正,則通常可能很快嘗試 scha_control()。
根據失敗歷史,公用程式 scds_fm_action() 會將資源狀況更新至 SCHA_RSSTATUS_OK、SCHA_RSSTATUS_DEGRADED 或 SCHA_RSSTATUS_FAULTED。 從而此狀況對於叢集系統管理來說是可用的。
在大多數情況下,應用程式特定的運作狀況檢查動作可以在單獨的獨立式公用程式 (例如,svc_probe()) 中實施,並與此一般主迴圈整合。
for (;;) { / * sleep for a duration of thorough_probe_interval between * successive probes. */ (void) scds_fm_sleep(scds_handle, scds_get_rs_thorough_probe_interval(scds_handle)); /* Now probe all ipaddress we use. Loop over * 1. All net resources we use. * 2. All ipaddresses in a given resource. * For each of the ipaddress that is probed, * compute the failure history. */ probe_result = 0; /* Iterate through the all resources to get each * IP address to use for calling svc_probe() */ for (ip = 0; ip < netaddr->num_netaddrs; ip++) { /* Grab the hostname and port on which the * health has to be monitored. */ hostname = netaddr->netaddrs[ip].hostname; port = netaddr->netaddrs[ip].port_proto.port; /* * HA-XFS supports only one port and * hence obtaint the port value from the * first entry in the array of ports. */ ht1 = gethrtime(); /* Latch probe start time */ probe_result = svc_probe(scds_handle, hostname, port, timeout); /* * Update service probe history, * take action if necessary. * Latch probe end time. */ ht2 = gethrtime(); /* Convert to milliseconds */ dt = (ulong_t)((ht2 - ht1) / 1e6); /* * Compute failure history and take * action if needed */ (void) scds_fm_action(scds_handle, probe_result, (long)dt); } /* Each net resource */ } /* Keep probing forever */ |