C++分布式實時應用框架——狀態中心模塊
技術交流合作QQ群:436466587 歡迎討論交流
版權聲明:本文版權及所用技術歸屬smartguys團隊所有,對於抄襲,非經同意轉載等行為保留法律追究的權利!
狀態中心是分布式系統中不可或缺的部分。一個分布式系統動輒上百個節點,這些節點相互間通訊關系的建立和維護;運行時每個節點的實時狀態數據采集和上報;系統管理模塊下達集群管理命令時,命令如何傳達到具體節點;集群節點故障時,如何檢測發現並及時進行處理,從而避免對集群運行產生影響。這些都是在分布式實時系統設計時需要考慮的功能性問題。更不用說,分布式環境下的數據一致性、二階段提交、腦裂、集群選主等復雜的分布式原生問題。狀態中心就為了解決這一系列問題而誕生的,是CDRAF(Cpp Distributed Real-time Application Framework)之所以能稱為“分布式”框架的核心和關鍵。
一、狀態中心模塊構成
狀態中心主要由兩個模塊組成。一是運行於多台主機或者節點上的分布式狀態中心集群(Distributed Status Center Cluster:DSCC)。DSCC上存儲了應用集群所有節點的狀態數據,節點間的連接關系,甚至做為管理命令的中轉站。之所以需要部署在多個節點是為了解決分布式環境中的單點問題。並且由於數據存儲了多份拷貝,DSCC還解決了數據一致性、二階段提交、腦裂、集群選主等復雜的分布式原生問題。另一個模塊是運行於分布式系統各個節點上的狀態中心代理(SmartAgent),SmartAgent主要負責上面提到的分布式系統的功能性問題,包括:從DSCC上獲取節點間通訊關系,建立分布式集群的通訊連接,並實時接受變更,動態地為集群增加或者刪除節點;采集每個節點的實時狀態數據並上報到DSCC;從DSCC上接收系統管理模塊下達的管理命令並執行。下圖淺綠色部分很好地詮釋了這一架構。
二、事件機制
分布式狀態中心集群(DSCC)通過事件機制與每個節點上的狀態中心代理(SmartAgent)保持信息聯系。當節點上SmartAgent對DSCC上的某個數據感興趣,就會到DSCC上注冊一個這個數據的通知。一旦DSCC上這個數據發生變化,相應注冊了通知的SmartAgent就會立刻接受到這個數據的變更通知。正是這一機制保證了分布式系統數據接收的實時性,並且避免了輪詢等其它方式產生的弊端。事件通知功能,是整個狀態中心功能的基石,其貫穿了狀態中心的各個功能模塊。如:當某個計算節點運行狀態發生變化,狀態中心中對應於該節點狀態數據即會發生變化,此時狀態中心向關心此事件的SmartAgent進程發出一個狀態改變的事件通知消息,消息中攜帶了狀態數據變化節點的主機名以及事件類型信息,以供SmartAgent進程獲取進行相關處理操作。
SmartAgent初始化時,需要對其在DSCC上感興趣的數據進行注冊,由於業務的復雜性,這類數據會非常之多。在設計時候,考慮到分布式系統的復雜性,以及功能的多樣性。將事件消息處理模塊設計為職責鏈模式,鏈上的每個節點都對應於CDRAF的某一功能。采用這樣的設計,極大了方便了CDRAF功能的擴展,在研發CDRAF過程中加入新的功能時,只要定義相關的消息,再寫好對應此消息的處理代碼即可。
三、狀態上報
當集群某個節點啟動時,由運行在此節點上的SmartAgent進程主動向DSCC上報本節點的屬性數據,這些數據有:節點的IP、對外提供各類服務所對應的端口號、節點的業務類型、主機名(設置於環境變量)、節點的運行狀態(正常、停止,啟動中、故障等)、當前節點的處理能力(CPU、TPS、時延等),這一系列用來描述當前節點的數據。當SmartAgent獲取到這些數據后,會周期性地將這些數據上傳到DSCC中。其它節點的SmartAgent和系統管理模塊便可以不斷取得這些更新的數據。
四、服務發現
對於一個分布式集群而言,集群的節點數是可以動態擴縮容的。不同類型的業務節點對外開放的端口也是會發生變化的。按傳統的做法,為每個服務訪問者配置服務地址列表到本地已不再可行。目前docker容器部署技術的火熱發展,很多企業的業務應用正在向docker部署轉移,已不再是部署在物理機或是虛擬機上。而我們知道docker容器在啟動前IP是未知的。基於這一系列的分布式系統特點,為CDRAF提供一個節點運行時服務注冊中心與發現功能就成了一個必須的要素了。DSCC所具有的內部存儲功能,可以很好的解決這一問題。當集群新增一個節點時,新節點向DSCC進行注冊后,集群原有的其它節點便可以從DSCC中得到新節點地址和端口等信息,並與之建立新的通訊關系。
五、容錯機制
CDRAF中對於每個節點的健康狀態進行了管理,節點實時上報健康狀態,並且節點與狀態中心間有心跳機制。如果節點因業務故障主動告知狀態中心故障狀態,或因網絡中斷、停電、主機故障等被動原因,節點在一定時間間隔內沒有主動上報健康狀態。狀態中心將把自己內部所存儲的該節點狀態描述設置為故障,並向集群中關心該節點的其它節點發送故障事件消息。其它節點在收到消息后即將消息中標記的該故障節點所自己的業務鏈中移出。防止其它節點繼續向故障節點發送消息,導致消息處理失敗。如果業務鏈中沒有該故障節點的備用節點,系統管理模塊將自動拉起一個新的節點以接替故障節點,注意在容器環境下,拉起一個新節點往往比重啟一個節點來得迅速,從而保障系統的正常運行。
六、優雅啟停
優雅啟停功能主要是為了解決集群中某個節點退出(從網絡中退出,或主動縮減節點)集群時,該節點消息隊列里可能還有未處理的消息。如果直接將連接斷開,那很有可能會丟失一定數量的未處理消息。雖然某些系統可以接受這樣的丟消息故障,只要分發節點在一定時長內沒收到響應消息就重新發送丟失的消息即可。但是這樣的處理,會對分發節點造其它的問題。所以在CDRAF是我們設計了“優雅啟停”這一節點主動退網功能。
當節點要進行退網時,狀中心會接收到相關的操作命令,狀態中心DSCC將此命令轉化成統一的事件,發送給相關的消息發送節點上的SmartAgent進程。SmartAgent進程收到事件消息后。通知本地的通訊平台的通訊監控程序。這時消息發送節點上的消息發送的進程將停止向將要退出網絡的節點發送消息,並斷開發送消息的連接。但是此時將要退出網絡的計算節點仍在處理消息,並且處理結果通過和消息發送節點的接收連接發送回去。也就是說,這里的關鍵是在消息發送節點與處理節點間建立了雙通道的網絡鏈路。對於消息發送節點而言,一類鏈路用於發送消息,另一類鏈路用於接收消息。當業務節點處理完自己消息隊列里所有消息時,業務節點主動斷開返回的消息連接。這樣就實現了不丟消息的退網功能。
未完待續……