|
隨著互聯(lián)網(wǎng)架構(gòu)的擴張,分布式系統(tǒng)變得日趨復雜,越來越多的組件開始走向分布式化,如微服務(wù)、消息收發(fā)、分布式數(shù)據(jù)庫、分布式緩存、分布式對象存儲、跨域調(diào)用,這些組件共同構(gòu)成了繁雜的分布式網(wǎng)絡(luò),那現(xiàn)在的問題是一個請求經(jīng)過了這些服務(wù)后其中出現(xiàn)了一個調(diào)用失敗的問題,只知道有異常,但具體的異常在哪個服務(wù)引起的就需要進入每一個服務(wù)里面看日志,這樣的處理效率是非常低的。 分布式調(diào)用鏈其實就是將一次分布式請求還原成調(diào)用鏈路。顯式的在后端查看一次分布式請求的調(diào)用情況,比如各個節(jié)點上的耗時、請求具體打到了哪臺機器上、每個服務(wù)節(jié)點的請求狀態(tài)等等。 鏈路跟蹤系統(tǒng)的功能1. 故障快速定位通過調(diào)用鏈跟蹤,一次請求的邏輯軌跡可以用完整清晰的展示出來。開發(fā)中可以在業(yè)務(wù)日志中添加調(diào)用鏈ID,可以通過調(diào)用鏈結(jié)合業(yè)務(wù)日志快速定位錯誤信息。 2. 各個調(diào)用環(huán)節(jié)的性能分析 在調(diào)用鏈的各個環(huán)節(jié)分別添加調(diào)用時延,可以分析系統(tǒng)的性能瓶頸,進行針對性的優(yōu)化。通過分析各個環(huán)節(jié)的平均時延,QPS等信息,可以找到系統(tǒng)的薄弱環(huán)節(jié),對一些模塊做調(diào)整,如數(shù)據(jù)冗余等。
3. 數(shù)據(jù)分析等調(diào)用鏈綁定業(yè)務(wù)后查看具體每條業(yè)務(wù)數(shù)據(jù)對應(yīng)的鏈路問題,可以得到用戶的行為路徑,經(jīng)過了哪些服務(wù)器上的哪個服務(wù),匯總分析應(yīng)用在很多業(yè)務(wù)場景。 4. 生成服務(wù)調(diào)用拓撲圖 通過可視化分布式系統(tǒng)的模塊和他們之間的相互聯(lián)系來理解系統(tǒng)拓撲。點擊某個節(jié)點會展示這個模塊的詳情,比如它當前的狀態(tài)和請求數(shù)量。
分布式調(diào)用跟蹤系統(tǒng)的設(shè)計1. 分布式調(diào)用跟蹤系統(tǒng)的設(shè)計目標低侵入性,應(yīng)用透明:作為非業(yè)務(wù)組件,應(yīng)當盡可能少侵入或者無侵入其他業(yè)務(wù)系統(tǒng),對于使用方透明,減少開發(fā)人員的負擔 低損耗:服務(wù)調(diào)用埋點本身會帶來性能損耗,這就需要調(diào)用跟蹤的低損耗,實際中還會通過配置采樣率的方式,選擇一部分請求去分析請求路徑 大范圍部署,擴展性:作為分布式系統(tǒng)的組件之一,一個優(yōu)秀的調(diào)用跟蹤系統(tǒng)必須支持分布式部署,具備良好的可擴展性 2. 埋點和生成日志 埋點即系統(tǒng)在當前節(jié)點的上下文信息,可以分為客戶端埋點、服務(wù)端埋點,以及客戶端和服務(wù)端雙向型埋點。埋點日志通常要包含以下內(nèi)容: TraceId、RPCId、調(diào)用的開始時間,調(diào)用類型,協(xié)議類型,調(diào)用方ip和端口,請求的服務(wù)名等信息; 調(diào)用耗時,調(diào)用結(jié)果,異常信息,消息報文等; 預(yù)留可擴展字段,為下一步擴展做準備; 3. 抓取和存儲日志日志的采集和存儲有許多開源的工具可以選擇,一般來說,會使用離線+實時的方式去存儲日志,主要是分布式日志采集的方式。典型的解決方案如Flume結(jié)合Kafka等MQ。 4. 分析和統(tǒng)計調(diào)用鏈數(shù)據(jù)一條調(diào)用鏈的日志散落在調(diào)用經(jīng)過的各個服務(wù)器上,首先需要按 TraceId 匯總?cè)罩?,然后按照RpcId 對調(diào)用鏈進行順序整理。用鏈數(shù)據(jù)不要求百分之百準確,可以允許中間的部分日志丟失。 5. 計算和展示匯總得到各個應(yīng)用節(jié)點的調(diào)用鏈日志后,可以針對性的對各個業(yè)務(wù)線進行分析。需要對具體日志進行整理,進一步儲存在HBase或者關(guān)系型數(shù)據(jù)庫中,可以進行可視化的查詢。 鏈路跟蹤Trace模型一次典型的分布式調(diào)用過程,如下圖所示:
Trace調(diào)用模型,主要有以下概念: Trace:一次完整的分布式調(diào)用跟蹤鏈路。 Span: 追蹤服務(wù)調(diào)基本結(jié)構(gòu),表示跨服務(wù)的一次調(diào)用; 多span形成樹形結(jié)構(gòu),組合成一次Trace追蹤記錄。 Annotation:在span中的標注點,記錄整個span時間段內(nèi)發(fā)生的事件。 BinaryAnnotation:可以認為是特殊的Annotation,用戶自定義事件。 Annotation類型:保留類型 Cs CLIENT_SEND,客戶端發(fā)起請求 Cr CLIENT_RECIEVE,客戶端收到響應(yīng) Sr SERVER_RECIEVE,服務(wù)端收到請求 Ss SERVER_SEND,服務(wù)端發(fā)送結(jié)果 用戶自定義類型: Event 記錄普通事件 Exception 記錄異常事件 Client && Server:對于跨服務(wù)的一次調(diào)用,請求發(fā)起方為client,服務(wù)提供方為server 各術(shù)語在一次分布式調(diào)用中,關(guān)系如下圖所示:
調(diào)用跟蹤系統(tǒng)的選型大的互聯(lián)網(wǎng)公司都有自己的分布式跟蹤系統(tǒng),比如Google的Dapper,Twitter的zipkin,淘寶的鷹眼,新浪的Watchman,京東的Hydra等,下面來簡單分析。 Google的DrapperDapper是Google生產(chǎn)環(huán)境下的分布式跟蹤系統(tǒng),Dapper有三個設(shè)計目標: 低消耗:跟蹤系統(tǒng)對在線服務(wù)的影響應(yīng)該做到足夠小。 應(yīng)用級的透明:對于應(yīng)用的程序員來說,是不需要知道有跟蹤系統(tǒng)這回事的。如果一個跟蹤系統(tǒng)想生效,就必須需要依賴應(yīng)用的開發(fā)者主動配合,那么這個跟蹤系統(tǒng)顯然是侵入性太強的。 延展性:Google至少在未來幾年的服務(wù)和集群的規(guī)模,監(jiān)控系統(tǒng)都應(yīng)該能完全把控住。 處理分為3個階段: ①各個服務(wù)將span數(shù)據(jù)寫到本機日志上; ②dapper守護進程進行拉取,將數(shù)據(jù)讀到dapper收集器里; ③dapper收集器將結(jié)果寫到bigtable中,一次跟蹤被記錄為一行。 阿里-鷹眼關(guān)于淘寶的鷹眼系統(tǒng),主要資料來自于內(nèi)部分享: 鷹眼埋點和生成日志:
如何抓取和存儲日志,記錄本地文件,使用額外的后臺進程定期(時間間隔?。┦占罩?。這種方式的優(yōu)勢在于對應(yīng)用的性能影響小,方便做消息堆積;但是需要在每臺業(yè)務(wù)server上都部署并管理日志收集agent,運維量比較大。
鷹眼的實現(xiàn)小結(jié):
注意Dapper與Eagle eye都不開源。 阿里EDAS+ARMS的立體化監(jiān)控體系通過阿里云提供的EDAS結(jié)合ARMS可以打造立體化監(jiān)控體系,其中EDAS用于應(yīng)用管控層面,用于控制鏈路和應(yīng)用;而ARMS更關(guān)注業(yè)務(wù)運營層面,如電商交易、車聯(lián)網(wǎng)、零售;實際上,監(jiān)控需要全方位關(guān)注業(yè)務(wù)、鏈路、應(yīng)用、系統(tǒng),通過ARMS與EDAS相互補全,形成了立體化監(jiān)控體系。 大眾點評——CAT架構(gòu)簡單??梢詫崿F(xiàn)一個Trace系統(tǒng)的所有功能。架構(gòu)如下圖所示:
跟蹤模型Transaction是最重要的事件消息類型,適合記錄跨越系統(tǒng)邊界的程序訪問行為,比如遠程調(diào)用,數(shù)據(jù)庫調(diào)用,也適合執(zhí)行時間較長的業(yè)務(wù)邏輯監(jiān)控,記錄次數(shù)與時間開銷。Transaction可嵌套。 跨服務(wù)的跟蹤功能與點評內(nèi)部的RPC框架集成,這部分未開源。 客戶端接入方式對于方法調(diào)用、sql、url請求等粒度較小的興趣點,需要業(yè)務(wù)人員手寫代碼實現(xiàn)。 日志收集方式直接向日志收集器發(fā)異步請求(有本地內(nèi)存緩存),一臺客戶端會連向幾個服務(wù)端,當一個服務(wù)端出問題,數(shù)據(jù)不會丟失。 當所有服務(wù)端都掛掉,消息會存入queue,當queue滿了,就丟棄了,沒有做數(shù)據(jù)存儲本地等工作。 全量采樣,系統(tǒng)繁忙的時候?qū)π阅苡绊戄^大(可能達到10%的影響) 最后一個穩(wěn)定版本是2014年1月,之后已經(jīng)失去維護。 京東-hydra與dubbo框架集成。對于服務(wù)級別的跟蹤統(tǒng)計,現(xiàn)有業(yè)務(wù)可以無縫接入。對于細粒度的興趣點,需要業(yè)務(wù)人員手動添加。架構(gòu)如下:
Hydra中跟蹤數(shù)據(jù)模型Trace:一次服務(wù)調(diào)用追蹤鏈路。 Span:追蹤服務(wù)調(diào)基本結(jié)構(gòu),多span形成樹形結(jié)構(gòu)組合成一次Trace追蹤記錄。 Annotation:在span中的標注點,記錄整個span時間段內(nèi)發(fā)生的事件。 BinaryAnnotation:屬于Annotation一種類型和普通Annotation區(qū)別,這鍵值對形式標注在span中發(fā)生的事件,和一些其他相關(guān)的信息。 日志收集方式與CAT類似。支持自適應(yīng)采樣,規(guī)則粗暴簡單,對于每秒鐘的請求次數(shù)進行統(tǒng)計,如果超過100,就按照10%的比率進行采樣。 開源項目已于2013年6月停止維護。 Twitter—OpenZipkin功能、數(shù)據(jù)跟蹤模型與hydra類似。Zipkin本身不開源,開源社區(qū)的是另外一套scala實現(xiàn),依托于finagle這個RPC框架。架構(gòu)如下:
Zipkin與其他Trace系統(tǒng)的不同之處在于: Zipkin中針對 HttpClient、jax-rs2、jersey/jersey2等HTTP客戶端封裝了攔截器??梢栽谳^小的代碼侵入條件下實現(xiàn)URl請求的攔截、時間統(tǒng)計和日志記錄等操作。 日志收集Cat是直接將日志發(fā)往消費集群;hydra是發(fā)給日志收集器,日志收集器推到消息隊列;Zipkin的client將統(tǒng)計日志發(fā)往消息隊列,日志收集器讀取后落地存儲;Dapper和Eagle eye是記錄本地文件,后臺進程定期掃描。 Trace系統(tǒng)現(xiàn)狀分析以上幾款鏈路跟蹤系統(tǒng)都各自滿足了請求鏈路追蹤的功能,但落實到我們自己的生產(chǎn)環(huán)境中時,這些Trace系統(tǒng)存在諸多問題:Google和alibaba的Trace系統(tǒng)不開源,但現(xiàn)階段來說阿里是做得最好的,如果用的是阿里的服務(wù)器,可考慮直接用阿里的追蹤系統(tǒng)以節(jié)省開發(fā)代價; 京東和點評的雖然開源,但是已經(jīng)多年沒有維護,項目依賴的jdk版本以及第三方框架過于陳舊等等,不適合用在生產(chǎn)環(huán)境中; Twitter的OpenZipkin使用scala開發(fā),而且其實現(xiàn)基于twitter內(nèi)部的RPC框架finagle,第三方依賴比較多,接入和運維的成本非常高。 如果不是用阿里的服務(wù),我們可以借鑒這些開源實現(xiàn)的思想, 自行開發(fā)Trace系統(tǒng)。那是自己從0開始開發(fā)還是基于開源方案二次開發(fā)? 這里面也要考慮到跨平臺,如NET和java環(huán)境,盡量減少原系統(tǒng)的侵入性或只需要更改少量的代碼即可接入,在這里可以基于zipkin和pinpoint進行二次開發(fā),功能可參考阿里的系統(tǒng)。 Zipkin 和 Pinpoint 選型對比Pinpoint 與 Zipkin 都是基于 Google Dapper 的那篇論文,因此理論基礎(chǔ)大致相同。Pinpoint 與 Zipkin 有明顯的差異,主要體現(xiàn)在如下幾個方面: 1. Pinpoint 是一個完整的性能監(jiān)控解決方案:有從探針、收集器、存儲到 Web 界面等全套體系;而 Zipkin 只側(cè)重收集器和存儲服務(wù),雖然也有用戶界面,但其功能與 Pinpoint 不可同日而語。反而 Zipkin 提供有 Query 接口,更強大的用戶界面和系統(tǒng)集成能力,可以基于該接口二次開發(fā)實現(xiàn)。 2. Zipkin 官方提供有基于 Finagle 框架(Scala 語言)的接口,而其他框架的接口由社區(qū)貢獻,目前可以支持 Java、Scala、Node、Go、Python、Ruby 和 C# 等主流開發(fā)語言和框架;但是 Pinpoint 目前只有官方提供的 Java Agent 探針,其他的都在請求社區(qū)支援中。 3. Pinpoint 提供有 Java Agent 探針,通過字節(jié)碼注入的方式實現(xiàn)調(diào)用攔截和數(shù)據(jù)收集,可以做到真正的代碼無侵入,只需要在啟動服務(wù)器的時候添加一些參數(shù),就可以完成探針的部署;而 Zipkin 的 Java 接口實現(xiàn) Brave,只提供了基本的操作 API,如果需要與框架或者項目集成的話,就需要手動添加配置文件或增加代碼。 4. Pinpoint 的后端存儲基于 HBase,而 Zipkin 基于 Cassandra。 接入難度因為 Brave 的注入需要依賴底層框架提供相關(guān)接口,因此并不需要對框架有一個全面的了解,只需要知道能在什么地方注入,能夠在注入的時候取得什么數(shù)據(jù)就可以了。就像上面的例子,我們根本不需要知道 MySQL 的 JDBC Driver 是如何實現(xiàn)的也可以做到攔截 SQL 的能力。但是 Pinpoint 就不然,因為 Pinpoint 幾乎可以在任何地方注入任何代碼,這需要開發(fā)人員對所需注入的庫的代碼實現(xiàn)有非常深入的了解,通過查看其 MySQL 和 Http Client 插件的實現(xiàn)就可以洞察這一點,當然這也從另外一個層面說明 Pinpoint 的能力確實可以非常強大,而且其默認實現(xiàn)的很多插件已經(jīng)做到了非常細粒度的攔截。 針對底層框架沒有公開 API 的時候,其實 Brave 也并不完全無計可施,我們可以采取 AOP 的方式,一樣能夠?qū)⑾嚓P(guān)攔截注入到指定的代碼中,而且顯然 AOP 的應(yīng)用要比字節(jié)碼注入簡單很多。 以上這些直接關(guān)系到實現(xiàn)一個監(jiān)控的成本,在 Pinpoint 的官方技術(shù)文檔中,給出了一個參考數(shù)據(jù)。如果對一個系統(tǒng)集成的話,那么用于開發(fā) Pinpoint 插件的成本是 100,將此插件集成入系統(tǒng)的成本是 0;但對于 Brave,插件開發(fā)的成本只有 20,而集成成本是 10。從這一點上可以看出官方給出的成本參考數(shù)據(jù)是 5:1。但是官方又強調(diào)了,如果有 10 個系統(tǒng)需要集成的話,那么總成本就是 10 * 10 + 20 = 120,就超出了 Pinpoint 的開發(fā)成本 100,而且需要集成的服務(wù)越多,這個差距就越大。 從短期目標來看,Pinpoint 確實具有壓倒性的優(yōu)勢:無需對項目代碼進行任何改動就可以部署探針、追蹤數(shù)據(jù)細粒化到方法調(diào)用級別、功能強大的用戶界面以及幾乎比較全面的 Java 框架支持。但是長遠來看,學習 Pinpoint 的開發(fā)接口,以及未來為不同的框架實現(xiàn)接口的成本都還是個未知數(shù)。相反,掌握 Brave 就相對容易,而且 Zipkin 的社區(qū)更加強大,更有可能在未來開發(fā)出更多的接口。在最壞的情況下,我們也可以自己通過 AOP 的方式添加適合于我們自己的監(jiān)控代碼,而并不需要引入太多的新技術(shù)和新概念。而且在未來業(yè)務(wù)發(fā)生變化的時候,Pinpoint 官方提供的報表是否能滿足要求也不好說,增加新的報表也會帶來不可以預(yù)測的工作難度和工作量。 最后還要考慮日志收集(直接發(fā)送、記錄到本地再上傳)、日志接收(消息隊列,直接進入ElasticSearch)、數(shù)據(jù)清洗(Logstach、Storm、SparkStreaming)、日志存儲(Mysql、Hbase、ElasticSearch)、頁面展示(自研還是直接用第三方的)。
|
|
|
來自: xujin3 > 《特定系統(tǒng)》