HealthMonitor是一個周期性工作的背景線程,它在一個循環中周期性的同HA服務進行心跳,負責跟蹤NameNode服務的健康狀況,并在健康狀況變化時調用failover控制器的回調方法。
HealthMonitor内部有如下主要成員變量:
1)背景工作線程:真正賣力幹活的
2)一些時間間隔、rpc逾時參數等配置資訊,見注釋
3)連接配接代理相關
4)螢幕s,狀态發生變化時需要周知螢幕s,故它們都實作了相同的接口
5)狀态
2.1、狀态
HealthMonitor定義了幾個狀态,如下:
分别對應了HealthMonitor監視服務健康狀況過程中的一些狀态,如下:
1)INITIALIZING:健康螢幕正在啟動;
2)SERVICE_NOT_RESPONDING:健康監測RPCs服務沒有響應,有可能是連接配接、rpc通訊問題等等;
3)SERVICE_HEALTHY:服務已連接配接且健康,這是一種比較理想的結果;
4)SERVICE_UNHEALTHY:服務正在運作但是不健康,這個結果也不賴,至少知道了服務不健康,也屬于正常的檢測結果;
5)HEALTH_MONITOR_FAILED:健康螢幕自己發生不可恢複故障且不能再提供準确資訊,糟糕透頂,監視線程本身出故障了。
2.2、螢幕回調接口
HealthMonitor定義了兩個接口,Callback和ServiceStateCallback,分别是在狀态發生變更和服務狀态發生變更時的,需要周知所有監聽器的回調方法,如下:
至于上述狀态和接口如何調用,在下面會詳解。
HealthMonitor的工作流程,主要看内部工作線程的執行,如下:
首先,監視背景線程的核心run()方法,在一個while循環内,循環的條件是shouldRun标志位:
1)循環直到連接配接上:不停的連接配接,直到連接配接上;
2)執行健康檢查。
如此簡單的兩步,下面我們需要看下以下問題:
1)如何連接配接?
2)如何執行健康檢查,得到檢查結果後如何處理?
1、如何連接配接?
分析loopUntilConnected()方法如下:
很簡單,通過targetToMonitor獲得代理,擷取成功的話,直接傳回,失敗的話線程休眠一段時間,繼續重試。
2、如何執行健康檢查,得到檢查結果後如何處理?
分析doHealthChecks()方法如下:
在一個while循環内,循環的依據同樣是shouldRun标志位為true,且線程會周期性休眠:
1)HA服務狀态status設定為null;
2)标志位healthy預設為false,即不健康;
3)擷取服務代理的服務狀态,并由代理執行健康檢查;
4)1、如果健康檢查能夠正确傳回,标志位healthy設定為true,表明服務健康;
2、抛出了異常:
2.1、如果是健康檢查失敗異常,調用enterState()方法,确定狀态為服務正在運作但是不健康;
2.1、否則調用enterState()方法,确定狀态為健康監測RPCs服務沒有響應,停止并清空代理,線程休眠一段時間,避免異常情況下沒有必要的重複嘗試;
5)設定上次服務狀态;
6)如果檢測結果為健康,則調用enterState()方法,确定狀态為服務已連接配接且健康;
7)工作線程周期性休眠。
可以看到,健康狀況的檢查是通過代理完成的,且,如果有檢查結果(無論是正常還是不正常,這裡的正常是指傳回了明确的結果,不正常隻通訊、連接配接或者線程本身出現問題),會通過enterState()方法通知監聽器s,如下:
而整體HA服務狀态也會通過setLastServiceStatus()方法,設定lastServiceState成員變量,并通知服務狀态監聽器,如下:
這也就是上述狀态和接口存在的意義。而監聽器的注冊和登出則是通過如下實作的:
HealthMonitor的構造及啟動是在ZKFailoverController的initHM()方法内完成的,它是整個Hadoop HDFS HA中的一個控制元件,初始化及啟動如下:
構造一個HealthMonitor執行個體,傳入的代理為localTarget,并注冊了一個state change的監聽器HealthCallbacks和service state change的監聽器ServiceStateCallBacks,然後調用start()方法啟動。
至于HealthMonitor如何與其它元件一起工作的,如何獲得的代理,代理怎麼執行監控檢查,監聽器如何處理健康檢查的結果,請關注後續文章。