我們一起聊聊分布式架構(gòu)中的可觀測(cè)性,看你了解幾分?
架構(gòu)
隨著分布式架構(gòu)逐漸成為主流,“可觀測(cè)性”一詞也日益頻繁地被人提起,它涉及的范圍比較廣泛,主要概括為如下三類:
- 聚合度量(metrics)
- 事件日志(logging)
- 鏈路追蹤(tracing)
這三個(gè)方向雖然各有千秋,各有側(cè)重,但是又不完全獨(dú)立。在Peter Bourgon 的文章《Metrics, Tracing, and Logging》系統(tǒng)地闡述了這三者的定義、特征,以及它們之間的關(guān)系與差異,受到了業(yè)界的廣泛認(rèn)可。
在實(shí)際的工作中,大家或多或少對(duì)上面三種都有一定的了解,只是沒(méi)有機(jī)會(huì)或者沒(méi)有需求去深入研究。
聚合度量(Metrics)
度量是一種計(jì)量單位,它是指對(duì)系統(tǒng)中某一指標(biāo)的統(tǒng)計(jì)聚合,然后通過(guò)聚合信息來(lái)揭示系統(tǒng)整體的運(yùn)行狀況。
度量總體上可分為客戶端的指標(biāo)收集、服務(wù)端的存儲(chǔ)查詢以及終端的監(jiān)控預(yù)警三個(gè)相對(duì)獨(dú)立的過(guò)程,每個(gè)過(guò)程一般都是不同的組件來(lái)完成,以Prometheus為例:
指標(biāo)可以通過(guò)直接抓取各種exporters,也可以從pushgateway抓取,然后存儲(chǔ)在TSDB(時(shí)序數(shù)據(jù)庫(kù))中,查詢指標(biāo)可以通過(guò)grafana,也可以通過(guò)prometheus web,報(bào)警則是通過(guò)altermanager實(shí)現(xiàn)。
可以看到,一個(gè)度量工具的內(nèi)部實(shí)現(xiàn)是很復(fù)雜的,在使用的時(shí)候也會(huì)損耗一定的資源。
目前來(lái)說(shuō),在云原生領(lǐng)域中,Prometheus占據(jù)了很大的主導(dǎo)地位,嚴(yán)格來(lái)說(shuō),它已經(jīng)成云原生監(jiān)控的標(biāo)配,下面我主要以Prometheus為例進(jìn)行介紹。
指標(biāo)收集
指標(biāo)收集主要包括兩部分:
- 指標(biāo)定義
- 指標(biāo)收集
相比于收集,指標(biāo)定義尤為重要,良好的指標(biāo)定義可以更直觀的反應(yīng)系統(tǒng)狀態(tài)。
最常用的黃金指標(biāo)有:
- 延遲:延遲是信息的發(fā)送方和接收方之間的時(shí)間延遲,以毫秒(ms)為單位。其原因通常是由于數(shù)據(jù)包丟失、網(wǎng)絡(luò)擁塞和稱為 “數(shù)據(jù)包延遲差異” 的網(wǎng)絡(luò)抖動(dòng)。延遲直接影響客戶體驗(yàn),轉(zhuǎn)化為成功請(qǐng)求的延遲和失敗請(qǐng)求的延遲。
- 流量:流量是系統(tǒng)上完成的工作量所帶來(lái)的壓力。它通過(guò)每秒查詢數(shù) (QPS) 或每秒事務(wù)數(shù) (TPS) 來(lái)衡量。企業(yè)通過(guò)數(shù)量來(lái)衡量這一點(diǎn):關(guān)鍵績(jī)效指標(biāo) (KPI) 是在給定時(shí)間訪問(wèn)網(wǎng)站的人數(shù)。這是與商業(yè)價(jià)值的直接關(guān)系。
- 錯(cuò)誤:錯(cuò)誤是根據(jù)整個(gè)系統(tǒng)中發(fā)生的錯(cuò)誤來(lái)衡量的。什么被視為服務(wù)錯(cuò)誤率的重要指標(biāo)!有兩類錯(cuò)誤,顯式錯(cuò)誤,例如失敗的 HTTP 請(qǐng)求(例如,500 個(gè)錯(cuò)誤代碼)。而一個(gè)隱含的錯(cuò)誤將是一個(gè)成功的響應(yīng),但與錯(cuò)誤的內(nèi)容或響應(yīng)時(shí)間長(zhǎng)。
- 飽和度:飽和度定義了服務(wù)的過(guò)載程度。它衡量系統(tǒng)利用率,強(qiáng)調(diào)資源和服務(wù)的整體能力。這通常適用于 CPU 使用率、內(nèi)存使用率、磁盤容量和每秒操作數(shù)等資源。儀表板和監(jiān)控告警是幫助您密切關(guān)注這些資源并幫助您在容量變得飽和之前主動(dòng)調(diào)整容量的理想工具。
- 利用率:雖然不是 “四大金信號(hào)” 的一部分,但值得一提;利用率告訴資源或系統(tǒng)有多忙。它以 %(百分比)表示,范圍為 0–100%。
所以在做指標(biāo)定義的時(shí)候,可以結(jié)合以上的黃金指標(biāo)進(jìn)行分類,但是并不代表每一種類型的應(yīng)用都需要滿足以上所有指標(biāo)。以系統(tǒng)監(jiān)控為例,如下表示是否需要監(jiān)控該類指標(biāo):
定義好資源指標(biāo)后,再來(lái)定義指標(biāo)具體的獲取方法。
目前,基于Prometheus監(jiān)控所實(shí)現(xiàn)的Exporter非常多,這些Exporter基本能夠拿到我們想要的指標(biāo),比如:
指標(biāo)查詢
指標(biāo)收集到Prometheus之后,會(huì)存儲(chǔ)到它的TSDB(時(shí)序數(shù)據(jù)庫(kù))中,我們可以在Prometheus Web中查詢需要的指標(biāo),如下獲取不同時(shí)間節(jié)點(diǎn)kubelet的HTTP請(qǐng)求總數(shù):
監(jiān)控預(yù)警
指標(biāo)度量是手段,最終目的是做分析和預(yù)警。
我們可以通過(guò)這些指標(biāo)制作監(jiān)控大屏,隨時(shí)觀察系統(tǒng)的狀態(tài),如下可以實(shí)時(shí)監(jiān)控Kubernetes中容器以及節(jié)點(diǎn)的狀態(tài):
良好的可視化能力對(duì)于提升度量系統(tǒng)的產(chǎn)品力十分重要,長(zhǎng)期趨勢(shì)分析(譬如根據(jù)對(duì)磁盤增長(zhǎng)趨勢(shì)的觀察判斷什么時(shí)候需要擴(kuò)容)、對(duì)照分析(譬如版本升級(jí)后對(duì)比新舊版本的性能、資源消耗等方面的差異)、故障分析(不僅從日志、追蹤自底向上可以分析故障,高維度的度量指標(biāo)也可能自頂向下尋找到問(wèn)題的端倪)等分析工作,既需要度量指標(biāo)的持續(xù)收集、統(tǒng)計(jì),往往還需要對(duì)數(shù)據(jù)進(jìn)行可視化,才能讓人更容易地從數(shù)據(jù)中挖掘規(guī)律。
還可以對(duì)重要的指標(biāo)進(jìn)行告警,以便維護(hù)人員能夠及時(shí)地介入排查問(wèn)題,如下是一個(gè)應(yīng)用JVM使用過(guò)載的告警。
但是,在做告警的時(shí)候需要綜合考慮指標(biāo)的重要程度,不是所有指標(biāo)都需要告警,不然就容易造成告警風(fēng)暴,最后就會(huì)真實(shí)演繹《狼來(lái)了》的故事。
事件日志(Logging)
日志用來(lái)記錄系統(tǒng)運(yùn)行期間所發(fā)生的事件,每個(gè)系統(tǒng)都應(yīng)該有日志。
日志是排查問(wèn)題的重要手段,大部分系統(tǒng)問(wèn)題最終都會(huì)追溯到日志上,所以良好的日志記錄有助于快速定位系統(tǒng)問(wèn)題。
但是,目前基本都是微服務(wù)多節(jié)點(diǎn)的形式存在,沒(méi)辦法像單機(jī)時(shí)代那樣簡(jiǎn)單使用命令就能獲取到日志內(nèi)容。而是需要把日志收集到專門的日志系統(tǒng),然后再進(jìn)行查詢、分析等。
目前比較受歡迎的開(kāi)源日志系統(tǒng)是ELK或者EFK,它在日志領(lǐng)域有著不可撼動(dòng)的地位。
事件日志也涉及以下幾個(gè)方面:
- 日志輸出
- 日志收集
- 日志查詢
- 日志告警
日志輸出
一千個(gè)開(kāi)發(fā)可能有一千個(gè)日志輸出方式,而且輸出的內(nèi)容千奇百怪,不管重要的或者不重要的都輸出到日志里,這將會(huì)導(dǎo)致日志查看困難,干擾大。
所以,良好的日志記錄習(xí)慣是非常重要的,在企業(yè)中應(yīng)該有專門的日志規(guī)范,這樣可以統(tǒng)一格式、統(tǒng)一標(biāo)準(zhǔn),不僅有助于收集,也有助于查看。
打印日志應(yīng)該盡量做到以下幾點(diǎn):
- 記錄請(qǐng)求的TraceID
- 記錄關(guān)鍵事件,包括上下文
- 不要打印敏感信息
- 合理規(guī)劃日志級(jí)別
日志收集
對(duì)于分布式服務(wù),為了能同時(shí)看到跨節(jié)點(diǎn)的全部日志,就需要把各種日志統(tǒng)一收集,比如使用Logstash或者Filebeat來(lái)收集日志,在日志收集的同時(shí)還可以對(duì)日志進(jìn)行處理,比如同一個(gè)應(yīng)用的日志可以建一條索引,同一個(gè)應(yīng)用的索引可以按天進(jìn)行創(chuàng)建等,這樣避免索引過(guò)大導(dǎo)致查詢困難等問(wèn)題。
如果在日志收集的過(guò)程中發(fā)現(xiàn)日志比較大,可以在收集處理的過(guò)程中先把日志寫入緩存或者消息隊(duì)列,避免直接寫入Elasticsearch導(dǎo)致其壓力過(guò)載。
日志查詢
收集到的日志最終是存儲(chǔ)在Elasticsearch中,它通常搭配Kibana一起使用,方便用戶操作。
Kibana 盡管只負(fù)責(zé)圖形界面和展示,但它提供的能力遠(yuǎn)不止讓你能在界面上執(zhí)行 Elasticsearch 的查詢那么簡(jiǎn)單。Kibana 宣傳的核心能力是“探索數(shù)據(jù)并可視化”,即把存儲(chǔ)在 Elasticsearch 中的數(shù)據(jù)被檢索、聚合、統(tǒng)計(jì)后,定制形成各種圖形、表格、指標(biāo)、統(tǒng)計(jì),以此觀察系統(tǒng)的運(yùn)行狀態(tài),找出日志事件中潛藏的規(guī)律和隱患。按 Kibana 官方的宣傳語(yǔ)來(lái)說(shuō)就是“一張圖片勝過(guò)千萬(wàn)行日志”。
日志告警
在做日志輸出的時(shí)候,對(duì)于一些有破壞性的日志需要特別標(biāo)記,當(dāng)遇到這類日志就需要及時(shí)的通知維護(hù)人員。我們可以使用ElastAlert來(lái)進(jìn)行告警處理。
ElastAlert是三方插件,通過(guò)查詢 ElasticSearch 中的記錄進(jìn)行比對(duì),通過(guò)配置報(bào)警規(guī)則對(duì)匹配規(guī)則的日志進(jìn)行警報(bào)。 ElastAlert 將Elasticsearch與兩種類型的組件(規(guī)則類型和警報(bào))結(jié)合使用,定期查詢Elasticsearch,并將數(shù)據(jù)傳遞到規(guī)則類型,該規(guī)則類型確定何時(shí)找到匹配項(xiàng)。發(fā)生匹配時(shí),將為該警報(bào)提供一個(gè)或多個(gè)警報(bào),這些警報(bào)將根據(jù)匹配采取行動(dòng)。
鏈路追蹤(Tracing)
有了度量和日志,在多數(shù)情況下已經(jīng)能滿足日常使用,但是它們有一個(gè)弊端,就是沒(méi)辦法很直觀的查看上下文,也無(wú)法有效的追蹤某個(gè)請(qǐng)求。
所以,就引入了鏈路追蹤。
從目標(biāo)來(lái)看,鏈路追蹤的目的是為排查故障和分析性能提供數(shù)據(jù)支持,系統(tǒng)對(duì)外提供服務(wù)的過(guò)程中,持續(xù)地接受請(qǐng)求并處理響應(yīng),同時(shí)持續(xù)地生成 Trace,按次序整理好 Trace 中每一個(gè) Span 所記錄的調(diào)用關(guān)系,便能繪制出一幅系統(tǒng)的服務(wù)調(diào)用拓?fù)鋱D。根據(jù)拓?fù)鋱D中 Span 記錄的時(shí)間信息和響應(yīng)結(jié)果(正?;虍惓7祷兀┚涂梢远ㄎ坏骄徛蛘叱鲥e(cuò)的服務(wù);將 Trace 與歷史記錄進(jìn)行對(duì)比統(tǒng)計(jì),就可以從系統(tǒng)整體層面分析服務(wù)性能,定位性能優(yōu)化的目標(biāo)。
從字面上看鏈路監(jiān)控的實(shí)現(xiàn)方式比較簡(jiǎn)單,然而在實(shí)際工作中卻比較復(fù)雜。主要在于企業(yè)業(yè)務(wù)系統(tǒng)可能采用不同的程序語(yǔ)言 ,每一種程序語(yǔ)言實(shí)現(xiàn)的方式都不一樣,這就導(dǎo)致工作量非常巨大,而且還要考慮以下幾點(diǎn):
- 低損耗:如果接入鏈路監(jiān)控不僅沒(méi)有解決問(wèn)題,反而加大了性能開(kāi)銷,這就得不償失。
- 透明:盡量在不加大開(kāi)發(fā)工作量,最好能做到無(wú)侵入接入。
- 易用:傻瓜式的使用方式比較受歡迎。
目前最常用的是Zipkin、Skywalking、Pinpoint等,它們都是基于服務(wù)追蹤實(shí)現(xiàn)的。
服務(wù)追蹤的實(shí)現(xiàn)思路是通過(guò)某些手段給目標(biāo)應(yīng)用注入追蹤探針(Probe),針對(duì) Java 應(yīng)用一般就是通過(guò) Java Agent 注入的。探針在結(jié)構(gòu)上可視為一個(gè)寄生在目標(biāo)服務(wù)身上的小型微服務(wù)系統(tǒng),它一般會(huì)有自己專用的服務(wù)注冊(cè)、心跳檢測(cè)等功能,有專門的數(shù)據(jù)收集協(xié)議,把從目標(biāo)系統(tǒng)中監(jiān)控得到的服務(wù)調(diào)用信息,通過(guò)另一次獨(dú)立的 HTTP 或者 RPC 請(qǐng)求發(fā)送給追蹤系統(tǒng)。
下面是使用Skywalking收集之后的查詢頁(yè)面。
最后
可觀測(cè)性平臺(tái)是一個(gè)很大很復(fù)雜的平臺(tái),大部門公司都是用一些開(kāi)源手段來(lái)堆疊,雖然能解決一些問(wèn)題,但是它們各自是相互獨(dú)立的,沒(méi)辦法很友好的進(jìn)行關(guān)聯(lián)。這也導(dǎo)致在排查問(wèn)題的時(shí)候需要各個(gè)平臺(tái)來(lái)回切換,而且每個(gè)平臺(tái)都需要一定的學(xué)習(xí)成本,這也導(dǎo)致許多公司安裝部署了,但是實(shí)際很少去用,沒(méi)有發(fā)揮其要實(shí)現(xiàn)的效果。
鏈接
【1】https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html
【2】https://skywalking.apache.org/
【3】https://www.elastic.co/cn/