vivo服務端監控架構設計與實踐

語言: CN / TW / HK

一、業務背景

當今時代處在資訊大爆發的時代,資訊藉助網際網路的潮流在全球自由的流動,產生了各式各樣的平臺系統和軟體系統,越來越多的業務也會導致系統的複雜性。

當核心業務出現了問題影響使用者體驗,開發人員沒有及時發現,發現問題時已經為時已晚,又或者當伺服器的CPU持續增高,磁碟空間被打滿等,需要運維人員及時發現並處理,這就需要一套有效的監控系統對其進行監控和預警。

如何對這些業務和伺服器進行監控和維護是我們開發人員和運維人員不可忽視的重要一環,這篇文章全篇大約5000多字,我將對vivo服務端監控的原理和架構演進之路做一次系統性整理,以便大家做監控技術選型時參考。

vivo服務端監控旨在為服務端應用提供包括系統監控、JVM監控以及自定義業務指標監控在內的一站式資料監控,並配套實時、多維度、多渠道的告警服務,幫助使用者及時掌握應用多方面狀態,事前及時預警發現故障,事後提供詳實的資料用於追查定位問題,提升服務可用性。目前vivo服務端監控累計接入業務方數量達到200+,本文介紹的是服務端監控,我司還有其他型別的優秀監控包括通用監控、呼叫鏈監控和客戶端監控等。

1.1 監控系統的基本流程

無論是開源的監控系統還是自研的監控系統,整體流程都大同小異。

1)資料採集:可以包括JVM監控資料如GC次數,執行緒數量,老年代和新生代區域大小;系統監控資料如磁碟使用使用率,磁碟讀寫的吞吐量,網路的出口流量和入口流量,TCP連線數;業務監控資料如錯誤日誌,訪問日誌,視訊播放量,PV,UV等。

2)資料傳輸:將採集的資料以訊息形式或者 HTTP 協議的形式等上報給監控系統。

3)資料儲存:有使用 MySQL、Oracle 等 RDBMS 儲存的,也有使用時序資料庫OpenTSDB、InfluxDB 儲存的,還有使用 HBase 直接儲存的。

4)資料視覺化:資料指標的圖形化展示,可以是折線圖,柱狀圖,餅圖等。

5)監控告警:靈活的告警設定,以及支援郵件、簡訊、IM 等多種通知通道。

1.2 如何規範的使用監控系統

在使用監控系統之前,我們需要了解監控物件的基本工作原理,例如JVM監控,我們需要清楚JVM的記憶體結構組成和常見的垃圾回收機制;其次需要確定如何去描述和定義監控物件的狀態,例如監控某個業務功能的介面效能,可以監控該介面的請求量,耗時情況,錯誤量等;在確定瞭如何監控物件的狀態之後,需要定義合理的告警閾值和告警型別,當收到告警提醒時,幫助開發人員及時發現故障;最後建立完善的故障處理體系,收到告警時迅速響應,及時處理線上故障。

二、vivo服務端監控系統架構及演進之路

在介紹vivo服務端監控系統架構之前,先帶大家瞭解一下OpenTSDB時序資料庫,在瞭解之前說明下為什麼我們會選擇OpenTSDB,原因有以下幾點:

1) 監控資料採集指標在某一時間點具有唯一值,沒有複雜的結構及關係。

2)監控資料的指標具有隨著時間不斷變化的特點。

3)基於HBase分散式、可伸縮的時間序列資料庫,儲存層不需要過多投入精力,具有HBase的高吞吐,良好的伸縮性等特點。

4)開源,Java實現,並且提供基於HTTP的應用程式程式設計介面,問題排查快可修改。

2.1 OpenTSDB簡介

1)基於HBase的分散式的,可伸縮的時間序列資料庫,主要用途就是做監控系統。譬如收集大規模叢集(包括網路裝置、作業系統、應用程式)的監控資料並進行儲存和查詢,支援秒級資料採集,支援永久儲存,可以做容量規劃,並很容易地接入到現有的監控系統裡,OpenTSDB的系統架構圖如下:

圖片

(來自官方文件)

儲存結構單元為Data Point,即某個Metric在某個時間點的數值。Data Point包括以下部分:

  • Metric,監控指標名稱;

  • Tags,Metric的標籤,用來標註類似機器名稱等資訊,包括TagKey和TagValue;

  • Value,Metric對應的實際數值,整數或小數;

  • Timestamp,時間戳。

核心儲存兩張表:tsdb和tsdb-uid。表tsdb用來儲存監控資料,如下圖:

圖片

(圖片出處:https://www.jianshu.com

Row Key為Metric+Timestamp的小時整點+TagKey+TagValue,取相應的位元組對映組合起來;列族t下的Qualifier為Timestamp的小時整點餘出的秒數,對應的值即為Value。

 表tsdb-uid用來儲存剛才提到的位元組對映,如下圖:

圖片

(圖片出處:https://www.jianshu.com

圖中的“001”表示tagk=hots或者tagv=static,提供正反查詢。

 2)OpenTSDB使用策略說明:

  • 不使用OpenTSDB提供的rest介面,通過client與HBase直連;

  • 工程端禁用compact動作的Thrd執行緒;

  • 間隔10秒獲取Redis緩衝資料批量寫入OpenTSDB。

2.2 OpenTSDB在實踐中需要關注的點

1)精確性問題

String value = "0.51";
float f = Float.parseFloat(value);
int raw = Float.floatToRawIntBits(f);
byte[] float_bytes = Bytes.fromInt(raw);
int raw_back = Bytes.getInt(float_bytes, 0);
double decode = Float.intBitsToFloat(raw_back);
/**
 * 列印結果:
 * Parsed Float: 0.51
 * Encode Raw: 1057132380
 * Encode Bytes: 3F028F5C
 * Decode Raw: 1057132380
 * Decoded Float: 0.5099999904632568
 */
System.out.println("Parsed Float: " + f);
System.out.println("Encode Raw: " + raw);
System.out.println("Encode Bytes: " + UniqueId.uidToString(float_bytes));
System.out.println("Decode Raw: " + raw_back);
System.out.println("Decoded Float: " + decode);

如上程式碼,OpenTSDB在儲存浮點型資料時,無法知悉儲存意圖,在轉化時會遇到精確性問題,即儲存"0.51",取出為"0.5099999904632568"。

2)聚合函式問題

OpenTSDB的大部分聚合函式,包括sum、avg、max、min都是LERP(linear interpolation)的插值方式,即所獲取的值存在被補缺的現象,對於有空值需求的使用很不友好。詳細原理參見OpenTSDB關於interpolation的文件

目前vmonitor服務端監控使用的OpenTSDB是我們改造後的原始碼,新增了nimavg函式,配合自帶的zimsum函式滿足空值插入需求。

2.3 vivo服務端監控採集器原理

圖片

1)定時器

內含3種採集器:OS採集器、JVM採集器和業務指標採集器,其中OS及JVM每分鐘執行採集和匯聚,業務指標採集器會實時採集並在1分鐘的時間點完成匯聚重置,3份採集器的資料打包上報至RabbitMQ,上報動作非同步超時。

2)業務指標採集器

業務指標採集方式有2種:日誌輸出過濾和工具類程式碼上報(侵入式),日誌輸出過濾是通過繼承log4j的Filter,從而獲取指標配置中指定的Appender輸出的renderedMessage,並根據指標配置的關鍵詞、聚合方式等資訊進行同步監聽採集;程式碼上報根據程式碼中指定的指標code進行message資訊上報,屬於侵入式的採集方式,通過呼叫監控提供的Util實現。業務指標配置每隔5分鐘會從CDN重新整理,內建多種聚合器供聚合使用,包括count計數、 sum求和、average平均、max最大值和min最小值統計。

2.4 vivo服務端監控老版本架構設計

圖片

1)資料採集及上報:需求方應用接入的監控採集器vmonitor-agent根據監控指標配置採集相應資料,每分鐘上報1次資料至RabbitMQ,所採用的指標配置每5分鐘從CDN下載更新,CDN內容由監控後臺上傳。

2)計算及儲存:監控後臺接收RabbitMQ的資料,拆解後儲存至OpenTSDB,供視覺化圖表呼叫,監控專案、應用、指標和告警等配置儲存於MySQL;通過Zookeeper和Redis實現分散式任務分發模組,實現多臺監控服務協調配合運作,供分散式計算使用。

3)告警檢測:從OpenTSDB獲取監控指標資料,根據告警配置檢測異常,並將異常通過第三方依賴自研訊息、簡訊傳送,告警檢測通過分散式任務分發模組完成分散式計算。

2.5 vivo服務端監控老版本部署架構

1)自建機房A:部署架構以國內為例,監控工程部署在自建機房A,監聽本機房的RabbitMQ訊息,依賴的Redis、OpenTSDB、MySQL、Zookeeper等均在同機房,需要上傳的監控指標配置由檔案服務上傳至CDN,供監控需求應用裝置呼叫。

2)雲機房:雲機房的監控需求應用裝置將監控資料上報至雲機房本地的RabbitMQ,雲機房的RabbitMQ將指定佇列通過路由的方式轉發至自建機房A的RabbitMQ,雲機房的監控配置通過CDN拉取。

2.6 vivo服務端監控新版本架構設計

圖片

1)採集(接入方):業務方接入vmonitor-collector,並在相應環境的監控後臺配置相關監控項即完成接入,vmonitor- collector將定時拉取監控項配置,採集服務資料並每分鐘上報。

2)資料聚合:老版本支援的是RabbitMQ將採集到的資料,路由至監控機房的RabbitMQ(同機房則不發生該行為),由監控後臺服務消費;CDN負責承載各應用的配置供應用定時拉取。新版本vmonitor-gateway作為監控資料閘道器,採用http方式上報監控資料以及拉取指標配置,拋棄了之前使用的RabbitMQ上報以及CDN同步配置的途徑,避免兩者故障時對監控上報的影響。

3)視覺化並且支援告警與配置(監控後臺vmonitor):負責前臺的資料多元化展示(包括業務指標資料,分機房彙總資料,單臺伺服器資料,以及業務指標複合運算呈現),資料聚合,告警(目前包括簡訊及自研訊息)等。

4)資料儲存:儲存使用HBASE叢集和開源的OpenTSDB作為聚合的中介,原始資料上報之後通過OpenTSDB持久化到HBase叢集,Redis作為分散式資料儲存排程任務分配、告警狀態等資訊,後臺涉及的指標和告警配置儲存於MySQL。

三、監控採集上報和儲存監控資料策略

為降低監控接入成本以及避免RabbitMQ上報故障和CDN同步配置故障對監控體系帶來的影響,將由採集層通過HTTP直接上報至代理層,並通過採集層和資料代理層的佇列實現災時資料最大程度的挽救。

圖片

詳細流程說明如下:

1)採集器(vmonitor-collector)根據監控配置每分鐘採集資料並壓縮,儲存於本地佇列(最大長度100,即最大儲存100分鐘資料),通知可進行HTTP上報,將資料上報至閘道器。

2)閘道器(vmonitor-gateway)接收到上報的資料後鑑權,認定非法即丟棄;同時判斷當前是否下層異常熔斷,如果發生則通知採集層重置資料退回佇列。

** 3)閘道器校驗**上報時帶來的監控配置版本號,過期則在結果返回時將最新監控配置一併返回要求採集層更新配置。

4)閘道器將上報的資料儲存於該應用對應的Redis佇列中(單個應用快取佇列key最大長度1w);儲存佇列完成後立即返回HTTP上報,表明閘道器已接受到資料,採集層可移除該條資料。

5)閘道器對Redis佇列資料進行解壓以及資料聚合;如果熔斷器異常則暫停前一行為;完成後通過HTTP儲存至OpenTSDB;如果儲存行為大量異常則觸發熔斷器。

四、核心指標

4.1 系統監控告警和業務監控告警

將採集到的資料通過OpenTSDB存放到HBase中後,通過分散式任務分發模組完成分散式計算。如果符合業務方配置的告警規則,則觸發相應的告警,對告警資訊進行分組並且路由到正確的通知方。可以通過簡訊自研訊息進行告警傳送,可通過名字、工號、拼音查詢錄入需要接收告警的人員,當接收到大量重複告警時能夠消除重複的告警資訊,所有的告警資訊可以通過MySQL表進行記錄方便後續查詢和統計,告警的目的不僅僅是幫助開發人員及時發現故障建立故障應急機制,同時也可以結合業務特點的監控項和告警梳理服務,借鑑行業最佳監控實踐。告警流程圖如下:

圖片

4.2 支援的告警型別以及計算公式

1)最大值:當指定欄位超過該值時觸發報警(報警閾值單位:number)。

2)最小值:當指定欄位低於該值時觸發報警(報警閾值單位:number)。

3)波動量:取當前時間到前15分鐘這段時間內的最大值或者最小值與這15分鐘內的平均值做浮動百分比報警,波動量需要配置波動基線,標識超過該基線數值時才做“報警閥值”判定,低於該基線數值則不觸發報警(報警閾值單位:percent)。

計算公式: 

波動量-向上波動計算公式:float rate = (float) (max - avg) / (float) avg;

波動量-向下波動計算公式:float rate = (float) (avg - min) / (float) avg;

波動量-區間波動計算公式:float rate = (float) (max - min) / (float) max;

4)日環比:取當前時間與昨天同一時刻的值做浮動百分比報警(報警閾值單位:percent)。

計算公式:float rate = (當前值 - 上一週期值)/上一週期值

5)周環比:取當前時間與上週同一天的同一時刻的值做浮動百分比報警(報警閾值單位:percent)。

計算公式:float rate = (當前值 - 上一週期值)/上一週期值

6)小時日環比:取當前時間到前一小時內的資料值總和與昨天同一時刻的前一小時內的資料值總和做浮動百分比報警(報警閾值單位:percent)。

計算公式:float rate = (float) (anHourTodaySum - anHourYesterdaySum) / (float) anHourYesterdaySum。

五、演示效果

5.1 業務指標資料查詢

1)查詢條件欄“指標”可選擇指定指標。

2)雙擊圖表上指標名稱可展示大圖,底部是根據起始時間的指標域合計值。

3)滾輪可以縮放圖表。

圖片

5.2 系統監控&JVM監控指標資料查詢

1)每分鐘頁面自動重新整理。

2)如果某行,即某臺機器整行顯示紅色,則代表該機器已逾半小時未上報資料,如機器是非正常下線就要注意排查了。

3)點選詳情按鈕,可以對系統&JVM監控資料進行明細查詢。

圖片

5.3 業務指標配置

 單個監控指標(普通)可以針對單個指定Appender的日誌檔案進行資料採集。

【必填】【指標型別】為“普通”、“複合”兩種,複合是將多個普通指標二次聚合,所以正常情況下需要先新增普通指標。

【必填】【圖表順序】正序排列,控制指標圖表在資料頁面上的展示順序。

【必填】【指標程式碼】預設自動生成UUID短碼。

【可選】【Appender】為log4j日誌檔案的appender名稱,要求該appender必須被logger的ref引用;如果使用侵入式採集資料則無需指定。

【可選】【關鍵字】為過濾日誌檔案行的關鍵詞。

【可選】【分隔符】是指單行日誌列分割的符號,一般為","英文逗號或其它符號。

圖片

六、主流監控對比

6.1 Zabbix

Zabbix 於 1998 年誕生,核心元件採用 C 語言開發,Web 端採用 PHP 開發,它屬於老牌監控系統中的優秀代表,能夠監控網路引數,伺服器健康和軟體完整性,使用也很廣泛。

Zabbix採用MySQL 進行資料儲存,所有沒有OpenTSDB支援 Tag的特性,因此沒法按多維度進行聚合統計和告警配置,使用起來不靈活。Zabbix 沒有提供對應的 SDK,應用層監控支援有限,也沒有我們自研的監控提供了侵入式的埋點和採集功能。

總體而言Zabbix 的成熟度更高,高整合度導致靈活性較差,在監控複雜度增加後,定製難度會升高,而且使用的MySQL關係型資料庫,對於大規模的監控資料插入和查詢是個問題。

6.2 Open-Falcon

OpenFalcon 是一款企業級、高可用、可擴充套件的開源監控解決方案,提供實時報警、資料監控等功能,採用 Go 和 Python 語言開發,由小米公司開源。使用 Falcon 可以非常容易的監控整個伺服器的狀態,比如磁碟空間,埠存活,網路流量等等。基於 Proxy-gateway,很容易通過自主埋點實現應用層的監控(比如監控介面的訪問量和耗時)和其他個性化監控需求,整合方便。

圖片

官方的架構圖如下:

圖片

6.3 Prometheus(普羅米修斯)

Prometheus是由SoundCloud開發的開源監控報警系統和時序列資料庫(TSDB),Prometheus使用Go語言開發,是Google BorgMon監控系統的開源版本。

和小米的Open-Falcon一樣,借鑑 OpenTSDB,資料模型中引入了 Tag,這樣能支援多維度的聚合統計以及告警規則設定,大大提高了使用效率。監控資料直接儲存在 Prometheus Server 本地的時序資料庫中,單個例項可以處理數百萬的 Metrics,架構簡單,不依賴外部儲存,單個伺服器節點可直接工作。

圖片

官方的架構圖如下:

圖片

6.4 vivo服務端監控vmonitor

vmonitor作為監控後臺管理系統,可以進行視覺化檢視,告警的配置,業務指標的配置等,具備JVM監控、系統監控和業務監控的功能。通過採集層(vmonitor-collector採集器)和資料代理層(vmonitor-gateway閘道器)的佇列實現災時資料最大程度的挽救。

提供了SDK方便業務方整合,支援日誌輸出過濾和侵入式程式碼上報資料等應用層監控統計,基於OpenTSDB時序開源資料庫,對其原始碼進行了改造,新增了nimavg函式,配合自帶的zimsum函式滿足空值插入需求,具有強大的資料聚合能力,可以提供實時、多維度、多渠道的告警服務。

圖片

七、總結

圖片

本文主要介紹了vivo服務端監控架構的設計與演進之路,是基於java技術棧做的一套實時監控系統,同時也簡單列舉了行業內主流的幾種型別的監控系統,希望有助於大家對監控系統的認識,以及在技術選型時做出更合適的選擇。

監控體系裡面涉及到的面很廣,是一個龐大複雜的體系,本文只是介紹了服務端監控裡的JVM監控,系統監控以及業務監控(包含日誌監控和工具類程式碼侵入式上報),未涉及到客戶端監控和全鏈路監控等,如果想理解透徹,必須理論結合實踐再做深入。

作者:vivo網際網路伺服器團隊-Deng Haibo