1. 程式人生 > >分散式鏈路監控追蹤分析與實踐(一)

分散式鏈路監控追蹤分析與實踐(一)

背景

隨著網際網路架構的擴張,分散式系統變得日趨複雜,越來越多的元件開始走向分散式化,如微服務、訊息收發、分散式資料庫、分散式快取、分散式物件儲存、跨域呼叫,這些元件共同構成了繁雜的分散式網路,那現在的問題是一個請求經過了這些服務後其中出現了一個呼叫失敗的問題,只知道有異常,但具體的異常在哪個服務引起的就需要進入每一個服務裡面看日誌,這樣的處理效率是非常低的。image

現實中的分散式服務之間的呼叫鏈比上圖還要複雜,像一張大網,盤根錯節。所以,我們急需一種能追蹤其呼叫鏈的方案,以快速完成問題的定位。

那什麼是分散式呼叫鏈呢?

分散式呼叫鏈其實就是將一次分散式請求還原成呼叫鏈路。顯式的在後端檢視一次分散式請求的呼叫情況,比如各個節點上的耗時、請求具體打到了哪臺機器上、每個服務節點的請求狀態等等。

鏈路追蹤系統應該具備的功能

根據前面的分析,我們已經知道追蹤分散式呼叫鏈是解決上述場景的一個可行方案,那分散式鏈路追蹤應該具備哪些功能才能達到我們的要求呢?

故障快速定位

通過呼叫鏈跟蹤,一次請求的邏輯軌跡可以用完整清晰的展示出來。開發中可以在業務日誌中新增呼叫鏈ID,可以通過呼叫鏈結合業務日誌快速定位錯誤資訊。

各個呼叫環節的效能分析

在呼叫鏈的各個環節分別新增呼叫時延,可以分析系統的效能瓶頸,進行鍼對性的優化。通過分析各個環節的平均時延,QPS等資訊,可以找到系統的薄弱環節,對一些模組做調整,如資料冗餘等。

資料分析

呼叫鏈繫結業務後檢視具體每條業務資料對應的鏈路問題,可以得到使用者的行為路徑,經過了哪些伺服器上的哪個服務,彙總分析應用在很多業務場景。

生成服務呼叫拓撲圖

通過視覺化分散式系統的模組和他們之間的相互聯絡來理解系統拓撲。點選某個節點會展示這個模組的詳情,比如它當前的狀態和請求數量。

分散式呼叫跟蹤系統的設計

我們前面已經說了鏈路追蹤系統需要具備的功能,那從哪些方面考慮去設計它呢?

(1)分散式呼叫跟蹤系統的設計目標

  • 低侵入性,應用透明:作為非業務元件,應當儘可能少侵入或者無侵入其他業務系統,對於使用方透明,減少開發人員的負擔
  • 低損耗:服務呼叫埋點本身會帶來效能損耗,這就需要呼叫跟蹤的低損耗,實際中還會通過配置取樣率的方式,選擇一部分請求去分析請求路徑
  • 大範圍部署,擴充套件性:作為分散式系統的元件之一,一個優秀的呼叫跟蹤系統必須支援分散式部署,具備良好的可擴充套件性

(2)埋點和生成日誌

  • 埋點即系統在當前節點的上下文資訊,可以分為客戶端埋點、服務端埋點,以及客戶端和服務端雙向型埋點。埋點日誌通常要包含以下內容:
  • TraceId、RPCId、呼叫的開始時間,呼叫型別,協議型別,呼叫方ip和埠,請求的服務名等資訊;
  • 呼叫耗時,呼叫結果,異常資訊,訊息報文等;
  • 預留可擴充套件欄位,為下一步擴充套件做準備;

(3)抓取和儲存日誌

日誌的採集和儲存有許多開源的工具可以選擇,一般來說,會使用離線+實時的方式去儲存日誌,主要是分散式日誌採集的方式。典型的解決方案如Flume結合Kafka等MQ。

(4)分析和統計呼叫鏈資料

一條呼叫鏈的日誌散落在呼叫經過的各個伺服器上,首先需要按 TraceId 彙總日誌,然後按照RpcId 對呼叫鏈進行順序整理。用鏈資料不要求百分之百準確,可以允許中間的部分日誌丟失。

(5)計算和展示

彙總得到各個應用節點的呼叫鏈日誌後,可以針對性的對各個業務線進行分析。需要對具體日誌進行整理,進一步儲存在HBase或者關係型資料庫中,可以進行視覺化的查詢。

鏈路追蹤Trace模型分析

目前,幾乎所有的分散式鏈路追蹤都是來自於谷歌的一篇論文而設計開發而成的,論文名稱:Dapper,大規模分散式系統的跟蹤系統

Trace呼叫模型,主要有以下概念:

  • Trace:一次完整的分散式呼叫跟蹤鏈路。
  • Span: 追蹤服務調基本結構,表示跨服務的一次呼叫; 多span形成樹形結構,組合成一次Trace追蹤記錄。
  • Annotation:在span中的標註點,記錄整個span時間段內發生的事件。
  • BinaryAnnotation:可以認為是特殊的Annotation,使用者自定義事件。
  • Annotation型別:保留型別
  • Cs CLIENT_SEND,客戶端發起請求
  • Cr CLIENT_RECIEVE,客戶端收到響應
  • Sr SERVER_RECIEVE,服務端收到請求
  • Ss SERVER_SEND,服務端傳送結果
  • 使用者自定義型別:
  • Event 記錄普通事件
  • Exception 記錄異常事件
  • Client && Server:對於跨服務的一次呼叫,請求發起方為client,服務提供方為server

各術語在一次分散式呼叫中,關係如下圖所示:image

呼叫跟蹤系統對比

當下網際網路環境,大的網際網路公司都有自己的分散式跟蹤系統,比如Google的Dapper,Twitter的zipkin,淘寶的鷹眼,新浪的Watchman,京東的Hydra等,下面來簡單分析。

Google的Drapper(閉源)

Dapper是Google生產環境下的分散式跟蹤系統,Dapper有三個設計目標:

  • 低消耗:跟蹤系統對線上服務的影響應該做到足夠小。
  • 應用級的透明:對於應用的程式設計師來說,是不需要知道有跟蹤系統這回事的。如果一個跟蹤系統想生效,就必須需要依賴應用的開發者主動配合,那麼這個跟蹤系統顯然是侵入性太強的。
  • 延展性:Google至少在未來幾年的服務和叢集的規模,監控系統都應該能完全把控住。

處理分為3個階段:

①各個服務將span資料寫到本機日誌上;

②dapper守護程序進行拉取,將資料讀到dapper收集器裡;

③dapper收集器將結果寫到bigtable中,一次跟蹤被記錄為一行。

大眾點評——CAT

架構簡單。可以實現一個Trace系統的所有功能。架構如下圖所示:image

跟蹤模型

Transaction是最重要的事件訊息型別,適合記錄跨越系統邊界的程式訪問行為,比如遠端呼叫,資料庫呼叫,也適合執行時間較長的業務邏輯監控,記錄次數與時間開銷。Transaction可巢狀。

跨服務的跟蹤功能與點評內部的RPC框架整合,這部分未開源。

客戶端接入方式

對於方法呼叫、sql、url請求等粒度較小的興趣點,需要業務人員手寫程式碼實現。

日誌收集方式

直接向日志收集器發非同步請求(有本地記憶體快取),一臺客戶端會連向幾個服務端,當一個服務端出問題,資料不會丟失。

當所有服務端都掛掉,訊息會存入queue,當queue滿了,就丟棄了,沒有做資料儲存本地等工作。

全量取樣,系統繁忙的時候對效能影響較大(可能達到10%的影響)

最後一個穩定版本是2014年1月,之後已經失去維護。

阿里-鷹眼(閉源)

  • 埋點和生成日誌
    • 基於中介軟體、TraceId/RpcId、非同步寫、取樣
  • 抓取和儲存日誌
    • 實時抓日誌,實時+離線結合的儲存
  • 彙總和重組呼叫鏈
    • 按TraceId彙總、按RpcId重組
  • 分析和統計呼叫鏈
    • 入口標準化、帶上下文的呼叫統計

京東-hydra

與dubbo框架整合。對於服務級別的跟蹤統計,現有業務可以無縫接入。對於細粒度的興趣點,需要業務人員手動新增。架構如下:image

Hydra中跟蹤資料模型

Trace: 一次服務呼叫追蹤鏈路。

Span: 追蹤服務調基本結構,多span形成樹形結構組合成一次Trace追蹤記錄。

Annotation: 在span中的標註點,記錄整個span時間段內發生的事件。

BinaryAnnotation: 屬於Annotation一種型別和普通Annotation區別,這鍵值對形式標註在span中發生的事件,和一些其他相關的資訊。

日誌收集方式

與CAT類似。支援自適應取樣,規則粗暴簡單,對於每秒鐘的請求次數進行統計,如果超過100,就按照10%的比率進行取樣。

開源專案已於2013年6月停止維護

Twitter—Zipkin

功能、資料跟蹤模型與hydra類似。Zipkin本身不開源,開源社群的是另外一套scala實現,依託於finagle這個RPC框架。架構如下:

image

Zipkin與其他Trace系統的不同之處

Zipkin中針對 HttpClient、jax-rs2、jersey/jersey2等HTTP客戶端封裝了攔截器。可以在較小的程式碼侵入條件下實現URl請求的攔截、時間統計和日誌記錄等操作。

日誌收集

  • Cat是直接將日誌發往消費叢集;
  • hydra是發給日誌收集器,日誌收集器推到訊息佇列;
  • Zipkin的client將統計日誌發往訊息佇列,日誌收集器讀取後落地儲存;
  • Dapper和Eagle eye是記錄本地檔案,後臺程序定期掃描。

Trace系統現狀分析

以上幾款鏈路跟蹤系統都各自滿足了請求鏈路追蹤的功能,但落實到我們自己的生產環境中時,這些Trace系統存在諸多問題:

  • Google和alibaba的Trace系統不開源,但現階段來說阿里是做得最好的,如果用的是阿里的伺服器,可考慮直接用阿里的追蹤系統以節省開發代價;
  • 京東和點評的雖然開源,但是已經多年沒有維護,專案依賴的jdk版本以及第三方框架過於陳舊等等,不適合用在生產環境中;
  • Twitter的OpenZipkin使用scala開發,而且其實現基於twitter內部的RPC框架finagle,第三方依賴比較多,接入和運維的成本比較高。

如果不是用阿里的服務,我們可以借鑑這些開源實現的思想, 自行開發Trace系統。那是自己從0開始開發還是基於開源方案二次開發? 這裡面也要考慮到跨平臺,如NET和java環境,儘量減少原系統的侵入性或只需要更改少量的程式碼即可接入,在這裡可以基於zipkin和pinpoint進行二次開發,功能可參考阿里的系統。

參考文章: