當(dāng)今時(shí)代處在信息大爆發(fā)的時(shí)代,信息借助互聯(lián)網(wǎng)的潮流在全球自由的流動(dòng),產(chǎn)生了各式各樣的平臺(tái)系統(tǒng)和軟件系統(tǒng),越來越多的業(yè)務(wù)也會(huì)導(dǎo)致系統(tǒng)的復(fù)雜性。
當(dāng)核心業(yè)務(wù)出現(xiàn)了問題影響用戶體驗(yàn),開發(fā)人員沒有及時(shí)發(fā)現(xiàn),發(fā)現(xiàn)問題時(shí)已經(jīng)為時(shí)已晚,又或者當(dāng)服務(wù)器的CPU持續(xù)增高,磁盤空間被打滿等,需要運(yùn)維人員及時(shí)發(fā)現(xiàn)并處理,這就需要一套有效的監(jiān)控系統(tǒng)對(duì)其進(jìn)行監(jiān)控和預(yù)警。
如何對(duì)這些業(yè)務(wù)和服務(wù)器進(jìn)行監(jiān)控和維護(hù)是我們開發(fā)人員和運(yùn)維人員不可忽視的重要一環(huán),這篇文章全篇大約5000多字,我將對(duì)vivo服務(wù)端監(jiān)控的原理和架構(gòu)演進(jìn)之路做一次系統(tǒng)性整理,以便大家做監(jiān)控技術(shù)選型時(shí)參考。
vivo服務(wù)端監(jiān)控旨在為服務(wù)端應(yīng)用提供包括系統(tǒng)監(jiān)控、JVM監(jiān)控以及自定義業(yè)務(wù)指標(biāo)監(jiān)控在內(nèi)的一站式數(shù)據(jù)監(jiān)控,并配套實(shí)時(shí)、多維度、多渠道的告警服務(wù),幫助用戶及時(shí)掌握應(yīng)用多方面狀態(tài),事前及時(shí)預(yù)警發(fā)現(xiàn)故障,事后提供詳實(shí)的數(shù)據(jù)用于追查定位問題,提升服務(wù)可用性。目前vivo服務(wù)端監(jiān)控累計(jì)接入業(yè)務(wù)方數(shù)量達(dá)到200+,本文介紹的是服務(wù)端監(jiān)控,我司還有其他類型的優(yōu)秀監(jiān)控包括通用監(jiān)控、調(diào)用鏈監(jiān)控和客戶端監(jiān)控等。
1.1 監(jiān)控系統(tǒng)的基本流程
無論是開源的監(jiān)控系統(tǒng)還是自研的監(jiān)控系統(tǒng),整體流程都大同小異。
1)數(shù)據(jù)采集:可以包括JVM監(jiān)控?cái)?shù)據(jù)如GC次數(shù),線程數(shù)量,老年代和新生代區(qū)域大??;系統(tǒng)監(jiān)控?cái)?shù)據(jù)如磁盤使用使用率,磁盤讀寫的吞吐量,網(wǎng)絡(luò)的出口流量和入口流量,TCP連接數(shù);業(yè)務(wù)監(jiān)控?cái)?shù)據(jù)如錯(cuò)誤日志,訪問日志,視頻播放量,PV,UV等。
2)數(shù)據(jù)傳輸:將采集的數(shù)據(jù)以消息形式或者 HTTP 協(xié)議的形式等上報(bào)給監(jiān)控系統(tǒng)。
3)數(shù)據(jù)存儲(chǔ):有使用 MySQL、Oracle 等 RDBMS 存儲(chǔ)的,也有使用時(shí)序數(shù)據(jù)庫(kù)OpenTSDB、InfluxDB 存儲(chǔ)的,還有使用 HBase 直接存儲(chǔ)的。
4)數(shù)據(jù)可視化:數(shù)據(jù)指標(biāo)的圖形化展示,可以是折線圖,柱狀圖,餅圖等。
5)監(jiān)控告警:靈活的告警設(shè)置,以及支持郵件、短信、IM 等多種通知通道。
1.2 如何規(guī)范的使用監(jiān)控系統(tǒng)
在使用監(jiān)控系統(tǒng)之前,我們需要了解監(jiān)控對(duì)象的基本工作原理,例如JVM監(jiān)控,我們需要清楚JVM的內(nèi)存結(jié)構(gòu)組成和常見的垃圾回收機(jī)制;其次需要確定如何去描述和定義監(jiān)控對(duì)象的狀態(tài),例如監(jiān)控某個(gè)業(yè)務(wù)功能的接口性能,可以監(jiān)控該接口的請(qǐng)求量,耗時(shí)情況,錯(cuò)誤量等;在確定了如何監(jiān)控對(duì)象的狀態(tài)之后,需要定義合理的告警閾值和告警類型,當(dāng)收到告警提醒時(shí),幫助開發(fā)人員及時(shí)發(fā)現(xiàn)故障;最后建立完善的故障處理體系,收到告警時(shí)迅速響應(yīng),及時(shí)處理線上故障。
二、vivo服務(wù)端監(jiān)控系統(tǒng)架構(gòu)及演進(jìn)之路
在介紹vivo服務(wù)端監(jiān)控系統(tǒng)架構(gòu)之前,先帶大家了解一下OpenTSDB時(shí)序數(shù)據(jù)庫(kù),在了解之前說明下為什么我們會(huì)選擇OpenTSDB,原因有以下幾點(diǎn):
1) 監(jiān)控?cái)?shù)據(jù)采集指標(biāo)在某一時(shí)間點(diǎn)具有唯一值,沒有復(fù)雜的結(jié)構(gòu)及關(guān)系。
2)監(jiān)控?cái)?shù)據(jù)的指標(biāo)具有隨著時(shí)間不斷變化的特點(diǎn)。
3)基于HBase分布式、可伸縮的時(shí)間序列數(shù)據(jù)庫(kù),存儲(chǔ)層不需要過多投入精力,具有HBase的高吞吐,良好的伸縮性等特點(diǎn)。
4)開源,Java實(shí)現(xiàn),并且提供基于HTTP的應(yīng)用程序編程接口,問題排查快可修改。
2.1 OpenTSDB簡(jiǎn)介
1)基于HBase的分布式的,可伸縮的時(shí)間序列數(shù)據(jù)庫(kù),主要用途就是做監(jiān)控系統(tǒng)。譬如收集大規(guī)模集群(包括網(wǎng)絡(luò)設(shè)備、操作系統(tǒng)、應(yīng)用程序)的監(jiān)控?cái)?shù)據(jù)并進(jìn)行存儲(chǔ)和查詢,支持秒級(jí)數(shù)據(jù)采集,支持永久存儲(chǔ),可以做容量規(guī)劃,并很容易地接入到現(xiàn)有的監(jiān)控系統(tǒng)里,OpenTSDB的系統(tǒng)架構(gòu)圖如下:
存儲(chǔ)結(jié)構(gòu)單元為Data Point,即某個(gè)Metric在某個(gè)時(shí)間點(diǎn)的數(shù)值。Data Point包括以下部分:
Metric,監(jiān)控指標(biāo)名稱;
Tags,Metric的標(biāo)簽,用來標(biāo)注類似機(jī)器名稱等信息,包括TagKey和TagValue;
Value,Metric對(duì)應(yīng)的實(shí)際數(shù)值,整數(shù)或小數(shù);
Timestamp,時(shí)間戳。
核心存儲(chǔ)兩張表:tsdb和tsdb-uid。表tsdb用來存儲(chǔ)監(jiān)控?cái)?shù)據(jù),如下圖:
Row Key為Metric+Timestamp的小時(shí)整點(diǎn)+TagKey+TagValue,取相應(yīng)的字節(jié)映射組合起來;列族t下的Qualifier為Timestamp的小時(shí)整點(diǎn)余出的秒數(shù),對(duì)應(yīng)的值即為Value。
表tsdb-uid用來存儲(chǔ)剛才提到的字節(jié)映射,如下圖:
圖中的“001”表示tagk=hots或者tagv=static,提供正反查詢。
2)OpenTSDB使用策略說明:
不使用OpenTSDB提供的rest接口,通過client與HBase直連;
工程端禁用compact動(dòng)作的Thrd線程;
間隔10秒獲取Redis緩沖數(shù)據(jù)批量寫入OpenTSDB。
2.2OpenTSDB在實(shí)踐中需要關(guān)注的點(diǎn)
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);
/**
* 打印結(jié)果:
* 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在存儲(chǔ)浮點(diǎn)型數(shù)據(jù)時(shí),無法知悉存儲(chǔ)意圖,在轉(zhuǎn)化時(shí)會(huì)遇到精確性問題,即存儲(chǔ)"0.51",取出為"0.5099999904632568"。
2)聚合函數(shù)問題
OpenTSDB的大部分聚合函數(shù),包括sum、avg、max、min都是LERP(linear interpolation)的插值方式,即所獲取的值存在被補(bǔ)缺的現(xiàn)象,對(duì)于有空值需求的使用很不友好。詳細(xì)原理參見OpenTSDB關(guān)于interpolation的文檔。
目前vmonitor服務(wù)端監(jiān)控使用的OpenTSDB是我們改造后的源碼,新增了nimavg函數(shù),配合自帶的zimsum函數(shù)滿足空值插入需求。
2.3vivo服務(wù)端監(jiān)控采集器原理
1)定時(shí)器
內(nèi)含3種采集器:OS采集器、JVM采集器和業(yè)務(wù)指標(biāo)采集器,其中OS及JVM每分鐘執(zhí)行采集和匯聚,業(yè)務(wù)指標(biāo)采集器會(huì)實(shí)時(shí)采集并在1分鐘的時(shí)間點(diǎn)完成匯聚重置,3份采集器的數(shù)據(jù)打包上報(bào)至RabbitMQ,上報(bào)動(dòng)作異步超時(shí)。
2)業(yè)務(wù)指標(biāo)采集器
業(yè)務(wù)指標(biāo)采集方式有2種:日志輸出過濾和工具類代碼上報(bào)(侵入式),日志輸出過濾是通過繼承l(wèi)og4j的Filter,從而獲取指標(biāo)配置中指定的Appender輸出的renderedMessage,并根據(jù)指標(biāo)配置的關(guān)鍵詞、聚合方式等信息進(jìn)行同步監(jiān)聽采集;代碼上報(bào)根據(jù)代碼中指定的指標(biāo)code進(jìn)行message信息上報(bào),屬于侵入式的采集方式,通過調(diào)用監(jiān)控提供的Util實(shí)現(xiàn)。業(yè)務(wù)指標(biāo)配置每隔5分鐘會(huì)從CDN刷新,內(nèi)置多種聚合器供聚合使用,包括count計(jì)數(shù)、 sum求和、average平均、max最大值和min最小值統(tǒng)計(jì)。
2.4 vivo服務(wù)端監(jiān)控老版本架構(gòu)設(shè)計(jì)
1)數(shù)據(jù)采集及上報(bào):需求方應(yīng)用接入的監(jiān)控采集器vmonitor-agent根據(jù)監(jiān)控指標(biāo)配置采集相應(yīng)數(shù)據(jù),每分鐘上報(bào)1次數(shù)據(jù)至RabbitMQ,所采用的指標(biāo)配置每5分鐘從CDN下載更新,CDN內(nèi)容由監(jiān)控后臺(tái)上傳。
2)計(jì)算及存儲(chǔ):監(jiān)控后臺(tái)接收RabbitMQ的數(shù)據(jù),拆解后存儲(chǔ)至OpenTSDB,供可視化圖表調(diào)用,監(jiān)控項(xiàng)目、應(yīng)用、指標(biāo)和告警等配置存儲(chǔ)于MySQL;通過Zookeeper和Redis實(shí)現(xiàn)分布式任務(wù)分發(fā)模塊,實(shí)現(xiàn)多臺(tái)監(jiān)控服務(wù)協(xié)調(diào)配合運(yùn)作,供分布式計(jì)算使用。
審核編輯:湯梓紅
-
監(jiān)控
+關(guān)注
關(guān)注
6文章
2212瀏覽量
55238 -
服務(wù)器
+關(guān)注
關(guān)注
12文章
9204瀏覽量
85548 -
vivo
+關(guān)注
關(guān)注
12文章
3306瀏覽量
63372
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論