更多文章,請移步微信公眾號《小姐姐味道》 mp原文 mp.weixin.qq.com/s?__biz=MzA… 監控是分散式系統的必備元件,能夠起到提前預警、問題排查、評估決策等功效,乃行走江湖、居家必備之良品。
監控系統概要
功能劃分
一個宿主機cpu
的報警叫做監控;一個業務日誌的報錯叫做監控;一個APM
條件的觸發,也叫做監控。分散式系統錯綜複雜,隨便做個統計指標的集合,也屬於監控的範疇。怎樣做到通用化,理清其中的關係,是需要花點功夫的,否則揉成一團,就不好拆了。
我習慣性從以下兩種型別對其進行劃分,真正實施起來,系統還是按照資料象限分比較合理:
資料象限 從資料型別劃分,大體可分為:日誌(logs
)、監控(metrics
)、呼叫鏈(tracing
)。
功能象限 從業務角度劃分,可分為:基礎監控、中介軟體監控、業務監控
不管什麼樣的監控系統,又涉及以下幾個模組過程: ❏ 資料收集。如何在廣度和效率上進行資料歸併。 ❏ 資料加工。資料的整理、傳輸和儲存。 ❏ 特稱提取。大資料計算,中間結果生成儲存。 ❏ 資料展示。高顏值、多功能顯示。
其中,特徵提取只有資料量達到一定程度才會開啟,因為它的開發和運維成本一般小公司是不會玩的。典型實現
不同的監控模組,側重於不同領域,有著不同的職責。我個人是傾向於 獨立設計 的,但需要做一定程度的整合,主要還是使用方式上的整合和優化。
我將從幾個典型解決方案說起,來說一下為什麼要分開設計,而不是揉成一團。
系統監控
系統監控用來收集宿主機的監控狀況(網路、記憶體、CPU、磁碟、核心等),包括大部分資料庫和中介軟體的敏感指標。這些metric
的典型特點是結構固定、有限指標項,使用時序資料庫進行儲存是最合適的。
指標收集方面,支援多樣化的元件將被優先下使用。比如telegraf
,支援所有的系統指標收集和大部分中介軟體和DB的指標收集。
在這裡特別推薦一下其中的
jolokia2
元件,可以很容易的實現JVM監控等功能。
指標收集以後,強烈建議使用kafka
進行一次緩衝。除了其逆天的堆積能力,也可以方便的進行資料共享(比如將nginx日誌
推送給安全組)。
參考本公眾號:【360度測試:KAFKA會丟資料麼?其高可用是否滿足需求?】
指標進入訊息佇列後,一份拷貝將會通過logstash
的過濾和整理入庫ES
等NoSQL
;另外一份拷貝,會經過流計算,統計一些指標(如QPS
、平均相應時間、TP值等)。
可以有多種途徑計算觸發報警的聚合計算。回查、疊加統計都是常用的手段。在資料量特別大的情況下,先對指標資料進行預處理是必備的,否則,再牛的DB
如influxdb
也承受不住。
展現方面,grafana
因其極高的顏值,首選,並支援通過iframe
嵌入到其他系統。其缺點也是顯著的:支援型別有限(同比、環比、斜率都木有);報警功能不是很好用。
怎麼?覺得這套技術棧過長?你其實是可以直接選擇zabbix
這種現成的解決方案元件的,它的外掛也夠多,小型公司用起來其實最爽不過了。但元件畢竟太集中了,你不方便將其打散,發現問題也不能任性的替換它的模組,這在架構上,是一個致命硬傷。最後突然發現,實現成本居然增加了。這也是為什麼上點規模的公司,都不在用它。
自己開發一個也是可行的,但不簡單,要處理各種複雜的前端問題,也不是每個人都能夠做漂亮。
日誌
說到日誌部分,大家首先想到的肯定是ELKB
啊。但我覺得ELKB
的鏈路不穩定不完整,建議做以下改造:
nginx
算是良民了),SLA
要求不會太高。
這時候收集部分就要用一些經的住考驗的日誌收集元件了。Logstash
的資源控制不是太智慧,為了避免爭搶業務資源,flume
、beats
是更好的選擇。
同樣,一個訊息佇列的緩衝是必要的,否則大量Agent
假死在業務端可不是鬧著玩的。
關於日誌落盤。很多日誌是沒必要入庫的,比如研發同學開開心心打出來的DEBUG日誌
,所以要有日誌規範。logstash
根據這些規範進行過濾,落庫到ES
。日誌量一般很大,按天建索引比較好。更久之前的日誌呢,可以歸集到日誌堡壘機(就是非常非常大的磁碟),或者直接放HDFS
裡存檔了。
那麼怎麼過濾業務日誌的錯誤情況呢,比如有多少XXX異常觸發報警。這種情況下可以寫指令碼,也可以接一份資料進行處理,然後生成監控項,拋給metrics收集器
即可。
哈!又繞回去了。
Tracing
相比較普通監控和日誌,呼叫鏈APM等就複雜的多了。除了有大量的資料產生源,也要有相應的業務元件來支援呼叫鏈聚合和展示。其功能展示雖然簡單,但卻是監控體系裡最複雜的模組。
Google 的論文
“Dapper, a Large-Scale Distributed Systems Tracing Infrastructure”
開啟了呼叫鏈的流行。後續可以說是百家齊放,直到近幾年才出現了OpenTracing
這樣的標準。
在資料處理和後續展示方面,它的技術點其實與監控技術是雷同的,複雜性主要體現在呼叫鏈資料的收集上。目前的實現方式,有類似Pinpoint
這種直接使用javaagent
技術修改位元組碼的;也有類似於cat
這種直接進行編碼的。其各有優缺點,但都需要解決以下問題:
❏ 收集元件的異構化。開發語言可能有java
,也可能有golang
❏ 元件的多樣化。從前端埋點開始,nginx、中介軟體、db等鏈路都需要包含
❏ 技術難點的攻關。如非同步、程式間上下文傳遞等
❏ 取樣。尤其在海量呼叫時,既要保證準確性,也要保證效率
關於Tracing的資料結構,已經爛大街,在此就不多說了。各種實現也各自為政,協議上相互不相容,做了很多重複的工作。為了解決不同的分散式追蹤系統 API 不相容的問題,誕生了 OpenTracing( opentracing.io/ ) 規範。說白了就是一套介面定義,主流的呼叫鏈服務端實現都相容此規範,如zipkin
、jaeger
。也就是說你只要按照規範提供了資料,就能夠被zipkin收集和展示。
OpenTracing大有一統天下的架勢,它在其中融合Tracing、Log、Metrics的概念。我們還是上張圖吧,等真正去做的時候去了解也不晚(來源於網路)。
值得一提的是,SpringCloud對它的支援還是比較全面的(github.com/opentracing…),但依賴關係和版本搞的非常混亂。建議參考後自己開發,大體使用"spring boot starter"技術,可以很容易的寫上一版。至於"Spring Cloud 2",更近一步,整合了micrometer
這種神器,對prometheus
整合也是非常的有好。業務metrics監控將省下不少力氣。
以上談了這麼多,僅僅是聊了一下收集方面而已。標準這個思路是非常對的,否則每個公司都要寫一遍海量的收集元件,多枯燥。至於國內大公司的產品,是否會主動向其靠攏,我們拭目以待。
服務端方面,我們以Uber
的Jaeger
為例,說明一下服務端需要的大體元件。
Jaeger Client - 就是上面我們所談的 Agent - 監聽在 UDP 埠上接收 span 資料的網路守護程式,它會將資料批量傳送給 collector Collector - 接收 jaeger-agent 傳送來的資料,然後將資料寫入後端儲存。 Data Store - 後端儲存被設計成一個可插拔的元件,支援將資料寫入 cassandra、ES Query - 接收查詢請求,然後從後端儲存系統中檢索 trace 並通過 UI 進行展示
是的,典型的無狀態系統,對等節點當機無影響。
分析和預警
上面的狀態圖不止一次提到流計算,這也不用非要整個Spark Streaming,從kafka接收一份資料自己處理也叫流計算,選用最新的kafka stream也是不從的選擇。重要的是聚合聚合聚合,重要的事情說三遍。
一般,算一些QPS,RT等,也就是純粹的計數;或者斜率,也就是增長下降速度;複雜點的有TP值(有百分之多少的請求在XX秒內相應),還有呼叫鏈的服務拓撲圖、日誌異常的統計,都可以在這裡進行計算。
幸運的是,流計算的API都比較簡單,就是除錯比較費勁。
分析後的資料屬於加工資料,是要分開儲存的,當然量小的話,也可以和原始資料混在一起。分析後的資料量是可評估的,比如5秒一條資料,一天就固定的17280條,預警模組讀的是分析後的資料(原始資料太大了),也會涉及大量的計算。
那麼分析後的統計資料用來幹什麼用呢?一部分就是預警;另一部分就是展示。
預警
拿我設計的一個原型來看,對一個metric的操作大體有以下內容:
❏ 在時間間隔內,某監控項觸發閾值XX次 ❏ 觸發動作有:大於、小於、平均值大於、平均值小於、環比大於、環比小於、同比大於、同比小於、自定義表示式等 ❏ 閾值為數字陣列,支援多監控項相互作用 ❏ 級別一般根據公司文化進行劃分,6層足夠了 ❏ 聚合配置用來表明是閾值觸發還是聚合觸發,比如在時間跨度5分鐘內發生5次,才算是處罰 ❏ 報警觸發後,會發郵件、打電話、發簡訊、發webhook等 僅做參考,這只是配置的冰山一角。要把各種出發動作做一遍,你是要浪費很多腦細胞的。展示
有很多視覺化js庫,但工作量一般都很大。但沒辦法,簡單的用grafana配置一下就可以了,複雜點的還需要親自操刀。我這裡有兩張簡單的grafana圖,可以參考一下。
[系統監控] [jvm監控一部分]小結
整體來說,整個體系就是收集、處理、應用這大三類資料(logs、metrics、trace)。其中有些元件的經驗可以共用,但收集部分和應用部分相差很大。我嘗試總結了一張圖,但從中只能看到有哪些元件參與,只看圖是臨摹兩可的。具體的資料流轉和處理,每種結構都不盡相同,這也是為什麼我一直強調分而治之的原因。但使用方式上,最好相差不要太大。無論後端的架構如何複雜,一個整體的外觀將讓產品變得更加清晰,你目前的工作,是不是也集中在此處呢?
一些元件
通過了解上面的內容,可以瞭解到我們習慣性的將監控系統所有的模組進行了拆解,你可以很容易的對其中的元件進行替換。比如beat替換flume、cassandra替換ES...
下面我將列出一些常用的元件,如有遺漏,歡迎補充。
資料收集元件
telegraf
用來收集監控項,influxdata家族的一員,是一個用Go編寫的代理程式,可收集系統和服務的統計資料,並寫入到多種資料庫。支援的型別可謂非常廣泛。
flume
主要用來收集日誌類資料,apache家族。Flume-og和Flume-ng版本相差很大。是一個高可用的,高可靠的,分散式的海量日誌採集、聚合和傳輸的系統,Flume支援在日誌系統中定製各類資料傳送方,用於收集資料;同時,Flume提供對資料進行簡單處理,並寫到各種資料接受方(可定製)的能力。
logstash
Logstash是一個開源的日誌收集管理工具,elastic家族成員。功能和flume類似,但佔用資源非常的貪婪,建議使用時獨立部署。功能豐富,支援ruby定義過濾條件。
StatsD
node開發,使用udp協議傳輸,專門用來收集資料,收集完資料就傳送到其他伺服器進行處理。與telegraf類似。
CollectD
collectd是一個守護(daemon)程式,用來定期收集系統和應用程式的效能指標,同時提供了機制,以不同的方式來儲存這些指標值。
視覺化
獨立的視覺化元件比較少,不過解決方案裡一般都帶一個web端,像grafana這麼專注的,不太多。
grafana
專注展示,顏值很高,整合了非常豐富的資料來源。通過簡單的配置,即可得到非常專業的監控圖。
儲存
有很多用的很少的,可以看這裡: grafana.com/plugins?typ…
influxdb
influx家族產品。Influxdb是一個開源的分散式時序、時間和指標資料庫,使用go語言編寫,無需外部依賴。支援的資料型別非常豐富,效能也很高。單節點使用時不收費的,但其叢集要收費。
opentsdb
OpenTSDB是一個時間序列資料庫。它其實並不是一個db,單獨一個OpenTSDB無法儲存任何資料,它只是一層資料讀寫的服務,更準確的說它只是建立在Hbase上的一層資料讀寫服務。能夠承受海量的分散式資料。
elasticsearch
能夠儲存監控項,也能夠儲存log,trace的關係也能夠儲存。支援豐富的聚合函式,能夠實現非常複雜的功能。但時間跨度太大的話,設計的索引和分片過多,ES容易懵逼。
解決方案
open-falcon
小米出品,它其實包含了agent、處理、儲存等模組,並有自己的dashboard,算是一個解決方案,贊一下。但目前用的較少,而且國內開源的東西尿性你也知道:公司內吹的高大上,社群用的卻是半成品。
Graphite
Graphite並不收集度量資料本身,而是像一個資料庫,通過其後端接收度量資料,然後以實時方式查詢、轉換、組合這些度量資料。Graphite支援內建的Web介面,它允許使用者瀏覽度量資料和圖。最近發展很不錯,經常和Collectd進行配對。grafana也預設整合其為資料來源。
prometheus
golang開發,發展態勢良好。它啟發於 Google 的 borgmon 監控系統,2015才正式釋出,比較年輕。prometheus目標巨集大,從其名字就可以看出來--普羅米修斯。另外,SpringCloud對它的支援也很好。
傳統監控
圖形還停留在使用AWT或者GD渲染上。總感覺這些東東處在淘汰的邊緣呢。
zabbix
使用佔位元別大,大到我不需要做過多介紹。但隨著節點的增多和服務的增多,大概在1k左右,你就會遇到瓶頸(包括開發定製瓶頸)。整體來說,小公司用的很爽,大公司用的很雞肋。
nagios
也算是比較古老了,時間久客戶多。其安裝配置相對較為複雜。功能不全較專一,個人不是很喜歡。
ganglia
Ganglia的核心包含gmond、gmetad以及一個Web前端。主要是用來監控系統效能,如:cpu 、mem、硬碟利用率, I/O負載、網路流量情況等,通過曲線很容易見到每個節點的工作狀態,對合理調整、分配系統資源,提高系統整體效能起到重要作用。
Centreon
這可是老掉牙了,和nagios配合的天衣無縫。你還在用麼?
APM
APM算是其中比較特殊的一個領域,也有很多實現。 附:支援OpenTracing的APM列表
cat
其實美團的東西非常少,大部分拿點評的來充門面。CAT作為美團點評基礎監控元件,它已經在中介軟體框架(MVC框架,RPC框架,資料庫框架,快取框架等)中得到廣泛應用,為美團點評各業務線提供系統的效能指標、健康狀況、基礎告警等。 算是比較良心了,但侵入性很大,如果你的程式碼量龐大就是噩夢。技術實現比較老,但控制力強。
Pinpoint
pinpoint是開源在github上的一款APM監控工具,它是用Java編寫的,用於大規模分散式系統監控。安裝agent是無侵入式的,也就是用了java的instrument技術,註定了是java系的。
SkyWalking
帶有華為標籤,和pinpoint類似,使用探針收集資料,2015年作品,使用ES作為儲存。進入Apache了哦,支援Opentracing。
zipkin
哦,zipkin也是走的這條路,但zipkin支援opentracing協議,這樣,你用的不爽可以替換它,非常大度。
jaeger
golang開發,Uber產品,小巧玲瓏,支援OpenTracing協議。它的Web端也非常漂亮,提供ES和Cassandra的後端儲存。
其他
Datadog
這裡提一個唯一收費的解決方案。為什麼呢?因為它做的很漂亮。顏值控,沒辦法。另外,還良心的寫了很多具體實現的程式碼和文件,質量很高。你要自己開發一套的話,不妨一讀。
監控體系的複雜之處就在於雜,如何理清其中的關係,給使用者一個合理的思考模式,才是最重要的,此所謂產品體驗優先。從整個的發展歷程中可以看到,標準化是對技術最好的改進,但也要經歷一個群魔亂舞的年代。既得利益者會維護自己的壁壘,拒絕接納和開放,然後猛然間發現,自己的東西已經落伍,跟不上時代的腳步了。