服務心跳機制主要用于確認服務的存活狀態(tài),UAVStack的心跳數(shù)據(jù)還負責上報節(jié)點的容器及進程監(jiān)控數(shù)據(jù),支持在前端實時查看應用容器和進程的運行狀態(tài),并根據(jù)這些數(shù)據(jù)對容器和進程做出預警。
在微服務架構中,服務心跳是一個簡單但非常重要的機制,用于確認微服務的存活狀態(tài)。UAVStack中的心跳是一個Http請求,MonitorAgent(以下簡稱MA)通過定時向HealthManager(以下簡稱HM)發(fā)送一個帶有特定報文格式的Http請求完成一次心跳的發(fā)送過程。心跳報文含有發(fā)送時的時間戳,用于更新HM端的數(shù)據(jù)狀態(tài)。
與普通的心跳不同,UAVStack中的心跳還負責上送MA端的應用容器和進程監(jiān)控數(shù)據(jù)。每次發(fā)送心跳的時候,在MA端會有定時任務去收集MA所在的應用容器心跳的基本信息,及應用容器上的進程數(shù)據(jù),隨著心跳數(shù)據(jù)包一起上送。
本文將首先介紹UAVStack的基礎心跳機制,之后對應用容器、進程的數(shù)據(jù)采集做詳細說明。
心跳的實現(xiàn)有很多種方式,心跳的發(fā)起可以由客戶端發(fā)起也可以由服務端發(fā)起,只需完成確認存活這一基本功能即可。但是在一般的實現(xiàn)中,我們更傾向于客戶端主動向服務端進行報告,因為當客戶端逐漸增加,單純通過服務端的輪詢會導致服務端的壓力,影響性能。
在UAVStack的實現(xiàn)中,我們也采用了這樣的方式,通過客戶端(MA)主動向服務端(HM)發(fā)送心跳信息,告知HM自身的存活情況。
一次心跳由UAV的MA和HM共同完成:
MA定時生成心跳數(shù)據(jù),攜帶MA節(jié)點的應用容器信息、進程信息以及服務信息,通過Http請求上報給HM;
HM負責將接收到的心跳數(shù)據(jù)存入Redis緩存,并定時掃描心跳數(shù)據(jù),確認節(jié)點的存活狀態(tài)。對于隨同的應用容器等監(jiān)控信息,會在Redis進行暫存,后續(xù)隨著HM的定時任務最終存入OpenTSDB進行落盤。整體的架構如下所示:
心跳服務主要流程如上圖所示,其邏輯有以下幾步:
1)MA的定時心跳任務生成一個空心跳數(shù)據(jù),將心跳數(shù)據(jù)交給MA端的容器、進程數(shù)據(jù)采集任務。
2)MA端的容器、進程數(shù)據(jù)采集任務負責產生心跳數(shù)據(jù)的時間戳、采集節(jié)點的應用容器、進程監(jiān)控數(shù)據(jù)、節(jié)點的基本信息、節(jié)點的可用服務信息等。經過以上過程之后,心跳數(shù)據(jù)將包含以下內容:
最后將心跳數(shù)據(jù)發(fā)送給HM。
3)HM端在接收到心跳數(shù)據(jù)之后,將其存入自身的Redis緩存。使用上報數(shù)據(jù)中的服務信息更新Redis中的服務狀態(tài),用于服務發(fā)現(xiàn)請求。
4)HM端在啟動心跳接收服務時,會同時啟動心跳檢查任務。這個任務會定時掃描Redis中的心跳數(shù)據(jù),根據(jù)當前系統(tǒng)時間與心跳時間戳的差,判斷心跳節(jié)點的存活狀態(tài),更新節(jié)點的狀態(tài),并對于過期的節(jié)點做刪除處理。
UAV的心跳數(shù)據(jù)除了完成心跳功能之外,還要上報節(jié)點的應用容器及進程的監(jiān)控數(shù)據(jù)。
將應用容器與進程數(shù)據(jù)通過Http方式上報是為了保證應用容器監(jiān)控數(shù)據(jù)與應用監(jiān)控數(shù)據(jù)的隔離,通過不同方式的上送可以保證在MQ服務不能使用時不影響容器與進程數(shù)據(jù)的采集。
本節(jié)將集中說明這些數(shù)據(jù)的采集細節(jié)。
應用容器的數(shù)據(jù)分為兩部分:
其一是容器的基本信息,即節(jié)點的ID,主機名,系統(tǒng)信息和JVM信息等;
另一部分是一些簡單的實時監(jiān)控采集數(shù)據(jù),包括CPU的負載、內存占用情況和磁盤占用情況等。這些數(shù)據(jù)在每次上報心跳數(shù)據(jù)的時候會分別從以下數(shù)據(jù)源實時采集:
不同于應用容器數(shù)據(jù)采集,進程的數(shù)據(jù)并不是在心跳進程中進行采集的,而是由專門的Feature負責。在Feature中將進程數(shù)據(jù)采集進一步分解成進程端口流量數(shù)據(jù)采集以及其他數(shù)據(jù)采集。這兩者均由定時任務完成,互相協(xié)作,最終由進程探測的定時任務更新心跳客戶端的進程數(shù)據(jù)。
這種使用多個采集任務分別采集的方式可以針對不同的數(shù)據(jù)進行不同頻度的采集。如對于網(wǎng)絡端口流量的采集,就可以以更長的周期進行,以減低數(shù)據(jù)采集帶來的性能損耗。同時,不同的任務也可以使用不同的線程執(zhí)行,提升執(zhí)行的效率。
進程數(shù)據(jù)采集流程大致如下圖所示:
進程端口流量探測定時任務每隔一定時間讀取本地變量端口列表,獲取要采集的端口號。
之后對于Windows環(huán)境,采用JPcap獲取網(wǎng)卡對象,并在網(wǎng)卡上設置tcp過濾器來統(tǒng)計一段時間內的端口流量。對于Linux環(huán)境則是直接通過調用Python腳本打開socket,分析流過的數(shù)據(jù)包獲得。
獲得全部端口上的流量數(shù)據(jù)后,任務會將采集數(shù)據(jù)交給進程數(shù)據(jù)采集任務,更新其本地變量,同時設置本次采集的時間戳。
進程探測定時任務由一系列子任務構成,在任務開始的時候,會先準備好一個Map結構的數(shù)據(jù)容器,用于存放采集到的進程信息,每個進程由pid區(qū)分,作為Map的key。
任務會先掃描所有的進程,獲取pid和進程的端口。掃描到的進程會經過一個過濾器排除不需要采集數(shù)據(jù)的進程,之后正式采集每個進程上的數(shù)據(jù)。
對于每一個進程,會通過運行系統(tǒng)命令采集連接數(shù)、CPU、內存占用,磁盤讀寫數(shù)據(jù)以及網(wǎng)絡端口流量數(shù)據(jù)。其中網(wǎng)絡端口流量數(shù)據(jù)是由端口流量探測任務采集并更新的本地變量,而進程探測任務也會將掃描到的最新的端口列表更新到端口流量探測任務的本地變量。
如果應用是部署在容器上的,則還會有對應的容器信息采集。最后進程探測任務會將采集到的進程數(shù)據(jù)更新到心跳客戶端的本地變量,隨著每次心跳數(shù)據(jù)的生成被一起采集并上報。
進程數(shù)據(jù)的采集分別來自以下數(shù)據(jù)源:
心跳數(shù)據(jù)和容器數(shù)據(jù)在通過Http上送到HM端之后,會由HM端對應的服務進行處理。
HM在啟動時會啟動自己的心跳客戶端,負責發(fā)送本機的心跳數(shù)據(jù)和采集HM所在容器的監(jiān)控數(shù)據(jù)。同時還會啟動一個心跳服務,負責接收處理所有上送的心跳和容器數(shù)據(jù)信息。
心跳服務在收到心跳數(shù)據(jù)請求后,會根據(jù)HM的配置,判定當前的HM是不是Master節(jié)點。如果HM是Master節(jié)點,心跳服務會從Http攜帶的報文中拿出上報的數(shù)據(jù),取得上報節(jié)點中的可用服務用于更新服務發(fā)現(xiàn)信息,之后將數(shù)據(jù)存入后端的Redis緩存中;如果不是Master節(jié)點,則會將數(shù)據(jù)移交至本機的心跳客戶端,由其下次發(fā)送心跳時一起上送。
這樣的設計是考慮到大規(guī)模監(jiān)控時會有跨機房的情況存在,此時各監(jiān)控節(jié)點往往不在同一個網(wǎng)段內,通過將同一個網(wǎng)段內的機器上交到邊界的“網(wǎng)關”統(tǒng)一上交可解決這一問題。此時的HM即充當著“網(wǎng)關”這一角色。
HM在啟動的時候同時還會啟動一個定時任務,這個任務負責處理各節(jié)點的存活狀況。任務定時從Redis中讀取全部心跳數(shù)據(jù),依次檢查上送心跳數(shù)據(jù)中的客戶端時間戳與當前系統(tǒng)時間戳的差值。
當時間超過一定的上送時間間隔之后,更改對應的節(jié)點存活狀態(tài)。當超過一倍上送時間間隔,意味節(jié)點可能死亡,處于dying狀態(tài)。當超過兩倍時間間隔時,意味著節(jié)點已經死亡。當超過三倍時間間隔時,心跳服務會刪除該節(jié)點的緩存記錄。
隨心跳一起上報的容器和進程數(shù)據(jù)會隨著心跳數(shù)據(jù)一同被存入Redis中,后續(xù)由HM的其他定時任務讀取并發(fā)送給預警中心進行處理,最終監(jiān)控指標被格式化成特定的結構存入OpenTSDB。
同時采集的容器數(shù)據(jù)和進程數(shù)據(jù)會提供前端AppHub查看界面,如圖所示:
點擊頁面上的每一個節(jié)點,可以查看詳細的節(jié)點信息,包括節(jié)點的操作系統(tǒng)信息、JVM信息、提供的服務和安裝的Feture等等。這些也就是前文所說的隨心跳數(shù)據(jù)上報的那部分信息。如圖所示:
心跳是微服務架構基礎但重要的機制,通過定時發(fā)送心跳數(shù)據(jù),MA節(jié)點報告了自身的存活狀態(tài),使得HM能夠知曉當前系統(tǒng)的運行狀態(tài)。
同時,UAVStack的心跳數(shù)據(jù)還同時負責上報節(jié)點的容器及進程監(jiān)控數(shù)據(jù),隨著這些數(shù)據(jù)的上報,HM可以對監(jiān)控的容器和進程做出預警,也能夠在前端實時看到應用容器和進程的運行狀態(tài)。
官方網(wǎng)站:https://uavorg.github.io/main/
開源地址:https://github.com/uavorg
作者:張明明
來源:宜信技術學院