kun:鳳凰網(wǎng)運(yùn)維開發(fā),負(fù)責(zé)公司運(yùn)維自動(dòng)化平臺(tái)設(shè)計(jì)開發(fā),InfluxDB contributer、open-falcon contributer 、golang愛好者。
說到監(jiān)控,大家肯定能列舉不少,zabbix、nagios、open-falcon、Prometheus等。鳳凰網(wǎng)和其他大多數(shù)互聯(lián)網(wǎng)公司一樣,一開始選擇了開源的zabbix來做為公司的監(jiān)控系統(tǒng)。就這樣,相安無事,多年過去了。隨著公司服務(wù)器的不斷增長,我們遇到了一些難題:
相信第一個(gè)問題很多體量稍大的公司都遇到過,大家用得最多的一個(gè)解決方案是拆分zabbix,部署多套來分擔(dān)壓力。但是后端查詢過慢的問題沒有從根本上解決,而且增加了維護(hù)成本,考慮到zabbix后端是c語言寫的,二次開發(fā)有一定難度,于是我們打算自己造個(gè)輪子。
先簡單介紹下幾個(gè)概念:
服務(wù)樹:某些公司為了方便管理服務(wù)集群,利用樹形結(jié)構(gòu)建立起了一種服務(wù)組織關(guān)系,方便集群 服務(wù)治理,以服務(wù)集群節(jié)點(diǎn)為管理單元,而不是某臺(tái)機(jī)器。
Open-Falcon:是小米開源的一套分布式高性能監(jiān)控系統(tǒng),支持服務(wù)樹管理。
有人可能會(huì)問,你們?yōu)槭裁床恢苯佑瞄_源的 open-falcon ,不得不承認(rèn), open-falcon 的某些設(shè)計(jì)還是非常不錯(cuò)的,我們也從中學(xué)習(xí)了很多思路。但是由于小米公司當(dāng)時(shí)沒有開源出結(jié)合監(jiān)控的服務(wù)樹,我們不得不自己設(shè)計(jì)一套適合自己,也可能適合你的服務(wù)樹。
基于服務(wù)樹,我們可以更方便的管理自己的服務(wù), 服務(wù)樹是整個(gè)監(jiān)控系統(tǒng)的基礎(chǔ)服務(wù),后來我們開發(fā)的發(fā)布系統(tǒng)也是基于服務(wù)樹實(shí)現(xiàn)的?;?golang 的運(yùn)維友好性和高性能,整個(gè)服務(wù)樹是用 golang 實(shí)現(xiàn)的,對(duì)于新手來說,上手難度也不高。服務(wù)樹架構(gòu)圖如下:
服務(wù)樹架構(gòu)圖
考慮到服務(wù)樹(service registry)組件的重要性,架構(gòu)上一定是高可用的,于是我們底層數(shù)據(jù)存儲(chǔ) store 層多實(shí)例是基于 raft 算法保證數(shù)據(jù)一致性的,最底層是用了 boltDB 來存儲(chǔ)服務(wù)樹的數(shù)據(jù),另外為了提高服務(wù)樹的讀性能我們還為 store 層添加了支持 lru 算法的 cache 模塊, cache 結(jié)構(gòu)體如下:
// Cache implements a non-thread safe fixed size LRU cache. type Cache struct { mu sync.RWMutex count int evictList *list.List items map[string]map[string]*list.Element size uint64 maxSize uint64 enable bool logger *log.Logger }
在啟動(dòng)服務(wù)樹的時(shí)候,我們可以指定服務(wù)樹開啟的內(nèi)存大小,現(xiàn)在我們開啟了 50M , 效果還是非常不錯(cuò)的。
如果你啟動(dòng)了 3 個(gè)實(shí)例,正常情況下 raft 底層是有一個(gè) leader 和兩個(gè) follower 的,寫操作必須落在 leader 上才能成功,很多開源軟件也都是這樣的,但是這樣服務(wù)樹就有狀態(tài)了,對(duì)于用戶提交數(shù)據(jù)不是特別友好。
于是我們?cè)?cluster 這一層會(huì)做判斷,如果進(jìn)來一個(gè)寫操作,直接嘗試本機(jī),如果失敗了,再把請(qǐng)求轉(zhuǎn)發(fā)到 leader 上,底層幫助用戶做數(shù)據(jù)轉(zhuǎn)發(fā),這樣用戶不用關(guān)心那個(gè)是 leader ,3臺(tái)對(duì)他來說是一樣的,前端加個(gè)負(fù)載均衡可以隨便接受請(qǐng)求了。
在這里我們底層還做了一些工作,就是把 cluster 監(jiān)聽的 TCP 端口和 raft 數(shù)據(jù)同步的端口復(fù)用,這樣,用戶的配置也就精簡了。
另外服務(wù)器可以根據(jù)一定策略自動(dòng)注冊(cè)到服務(wù)樹上的某個(gè)服務(wù)節(jié)點(diǎn)當(dāng)中,機(jī)器,報(bào)警,權(quán)限在服務(wù)中都是一種資源,這種資源都有增刪改查的操作,對(duì)于服務(wù)樹來說這些沒有什么區(qū)別,只是人定義了它,服務(wù)樹中一切皆資源,后期擴(kuò)展極為方便。
zabbix 很大的一個(gè)問題就是用結(jié)構(gòu)型數(shù)據(jù)庫來存儲(chǔ)了時(shí)序性數(shù)據(jù)??紤]到整個(gè)監(jiān)控系統(tǒng)的配置數(shù)據(jù)和監(jiān)控指標(biāo)數(shù)據(jù)是有不同特點(diǎn)的:
可以考慮把監(jiān)控配置數(shù)據(jù)抽象城資源存儲(chǔ)到服務(wù)樹中,保證數(shù)據(jù)可用性,而對(duì)于監(jiān)控指標(biāo)數(shù)據(jù)可以存儲(chǔ)到時(shí)序性數(shù)據(jù)庫當(dāng)中,開源的有 OpenTSDB、InfluxDB、Prometheus等。
業(yè)務(wù)上有越來越多上報(bào)打點(diǎn)需求,我們可以考慮從 agent 端開放出接口,把業(yè)務(wù)上報(bào)的數(shù)據(jù)作為普通數(shù)據(jù)一起打包入庫,這樣也復(fù)用了監(jiān)控系統(tǒng)數(shù)據(jù)傳遞的整條鏈路,同時(shí)降低了系統(tǒng)維護(hù)難度。對(duì)于一些標(biāo)準(zhǔn)的基礎(chǔ)服務(wù)采集,我們采用插件的方式來實(shí)現(xiàn),在 zabbix 中叫模板,比如 nginx 的一些指標(biāo), mysql 的一些指標(biāo)等。
設(shè)計(jì)需求分析完了,關(guān)于鳳凰網(wǎng)的監(jiān)控架構(gòu),我們先上架構(gòu)圖:
服務(wù)器通過拉取服務(wù)樹的用戶配置采集策略,通過部署的agent進(jìn)行監(jiān)控?cái)?shù)據(jù)采集上報(bào),每個(gè)IDC內(nèi)部會(huì)有一個(gè)消息隊(duì)列防止公網(wǎng)傳輸延遲或丟數(shù)據(jù),數(shù)據(jù)會(huì)進(jìn)入消息隊(duì)列,然后會(huì)有router模塊負(fù)責(zé)把數(shù)據(jù)寫入到InfluxDB中。
由于InfluxDB已經(jīng)閉源了集群功能,為了保證后端數(shù)據(jù)的高可用,我們通過router進(jìn)行多寫。受限于大量的寫入請(qǐng)求,我們通過router對(duì)后端InfluxDB做了分片,這樣當(dāng)后端某個(gè)db出問題時(shí),不至于影響其他服務(wù)數(shù)據(jù)寫入和報(bào)警。
報(bào)警我們用了開源的kapacitor,為了提高用戶易用性,我們圍繞它做了一些改進(jìn),也在支持了監(jiān)控指標(biāo)的無值監(jiān)控。
InfluxDB是一個(gè)時(shí)序數(shù)據(jù)庫,為時(shí)序數(shù)據(jù)而生,它新版的TSM存儲(chǔ)引擎性能非常好,數(shù)據(jù)壓縮做的非常好。
舉個(gè)例子,2000臺(tái)左右服務(wù)器,100天數(shù)據(jù)占用400G空間。面對(duì)10s級(jí)別的上報(bào)采集頻率,這個(gè)成績是非常不錯(cuò)的。
目前,監(jiān)控系統(tǒng)大部分監(jiān)控項(xiàng)是10秒級(jí)的上報(bào)粒度,InfluxDB的每秒寫入5w。每天入庫的數(shù)據(jù)點(diǎn)10億。
agent原生支持Windows,開源社區(qū)支持linux做的比較好,但是我們公司有些微軟的服務(wù)(exchange)是windows服務(wù)器,于是我們做了很多工作來原生支持win系統(tǒng),
支持windows的相關(guān)源文件
支持第三方打點(diǎn)上報(bào),方便開發(fā)接入監(jiān)控系統(tǒng),我認(rèn)為這個(gè)已經(jīng)是現(xiàn)在監(jiān)控系統(tǒng)的標(biāo)配了。
監(jiān)控上報(bào)
插件庫支持豐富,得益于開源社區(qū),支持插件監(jiān)控,擁有完善的插件庫
相關(guān)插件
更優(yōu)化的圖像展示速度,在長時(shí)間跨度查詢的時(shí)候能夠做到快速展示, 支持grafana展示 (原生支持)
儀表板顯示
支持自動(dòng)注冊(cè),服務(wù)器根據(jù)主機(jī)名自動(dòng)注冊(cè)到服務(wù)樹相應(yīng)節(jié)點(diǎn),根據(jù)節(jié)點(diǎn)的配置自動(dòng)采集和報(bào)警
新節(jié)點(diǎn)注冊(cè)
更優(yōu)化的agnet,agnet的安全性和性能是我們非常關(guān)注的問題,我們盡可能降低agent的資源消耗(mem.used<30MB cpu.used<1%),為此我們還砍了一些采集項(xiàng)。
內(nèi)存占用率
CPU占用率
支持分級(jí)報(bào)警,方便值班人員看到正在發(fā)生的報(bào)警,每個(gè)報(bào)警持續(xù)的時(shí)長,以及是否恢復(fù)。
報(bào)警DashBord
靈活的機(jī)器管理,你可以看到當(dāng)前機(jī)器有無報(bào)警,機(jī)器狀態(tài)是否online,如果機(jī)器維護(hù)可以隨時(shí)設(shè)置為維護(hù)狀態(tài),屏蔽這臺(tái)機(jī)器的所有報(bào)警,專注于處理問題。
機(jī)器管理
回到文章開頭遇到的問題,我們借助于現(xiàn)有的開源時(shí)序數(shù)據(jù)庫,大量監(jiān)控?cái)?shù)據(jù)的寫入和讀取已經(jīng)不是問題了。
服務(wù)樹的出現(xiàn)可以更好的幫助運(yùn)維人員管理自己的服務(wù)集群,同時(shí)我們?cè)?agent 端開啟了一個(gè) unix domain socket 用于本機(jī)的業(yè)務(wù)上報(bào),這是一個(gè)異步接口,不會(huì)阻塞請(qǐng)求,甚至可以把監(jiān)控平臺(tái)看成是一個(gè)開放的消息總線,通過這個(gè)上報(bào)接口,給了自己和他人一個(gè)無限可能。
未來的監(jiān)控系統(tǒng)肯定會(huì)更加智能,這也是最近比較火的“AIOPS”的一部分,運(yùn)維監(jiān)控系統(tǒng)擁有大量的監(jiān)控原始數(shù)據(jù)卻沒能發(fā)揮它的價(jià)值,通過分析這部分?jǐn)?shù)據(jù)我們可以挖掘很多潛在的有價(jià)值的信息,從而降低運(yùn)維成本,提高運(yùn)維效率,這部分?jǐn)?shù)據(jù)甚至可以通過人工標(biāo)注后進(jìn)行機(jī)器學(xué)習(xí),這樣監(jiān)控系統(tǒng)就可以不用設(shè)置報(bào)警策略來進(jìn)行報(bào)警了。
機(jī)器學(xué)習(xí)、人工智能的盛行給運(yùn)維工作帶來更多暢想和變革,這也是我們正在努力的方向。
聯(lián)系客服