一、Jaeger是什么
Uber開發的一個受Dapper和Zipkin啟發的分布式跟蹤系統.后端用Go實現,前端用React實現。
官方地址:https://www.jaegertracing.io
適用於以下場景:
- 分布式跟蹤信息傳遞
- 分布式事務監控
- 服務依賴性分析
- 展示跨進程調用鏈
- 定位問題
- 性能優化
Ps:關於分布式追蹤系統可以看這篇文章 分布式追蹤系統概述及主流開源系統對比
二、Jaeger架構
1. 術語
OpenTracing
為了解決不同的分布式追蹤系統 API 不兼容的問題,誕生了 OpenTracing 規范。OpenTracing 是一個輕量級的標准化層,它位於應用程序/類庫和追蹤或日志分析程序之間。
一句話總結,OpenTracing是一套標准,它通過提供平台無關、廠商無關的API,使得開發人員能夠方便的添加(或更換)追蹤系統的實現(我們在測試使用中是基本上通過兩行代碼的更改就可以在Zipkin和Jaeger之間切換)。OpenTracing提供了用於運營支撐系統的和針對特定平台的輔助程序庫。程序庫的具體信息請參考詳細的規范。OpenTracing 已進入 CNCF(雲原生計算基金會,著名的Kubernetes、gRPC和Prometheus等均孵化於此),正在為全球的分布式追蹤,提供統一的概念和數據標准。
兩個核心
-
Span: 記錄Trace在執行過程中的信息,如:查詢的sql,請求的HTTP地址,RPC調用,開始、結束、間隔時間等。是跟蹤的最小邏輯單位,Span間可以是嵌套關系。
-
Trace: 追蹤對象,一個Trace代表了一個服務或者流程在系統中的執行過程,如:test.com,redis,mysql等執行過程。一個Trace是由多個Span組成的有向無環圖,代表一次完整的跟蹤
結合跟蹤鏈來理解這兩個術語。
跟蹤鏈
如下圖所示:
這張圖是Google的Dapper論文里的一個例子:圖示中,A~E五個節點表示五個服務。用戶發起一次請求RequestX到A,同時由於該請求依賴服務B與C,因此A分別發送RPC請求到B和C,B處理完請求后會直接返回到A,但是服務C還依賴服務D和E,因此還要發起兩個RPC請求分別到D和E,D和E處理完畢后回到C,C才繼續回復到A,最終A會回復用戶ReplyX。對於這樣一個請求,簡單實用的分布式跟蹤的實現,就是為服務器上每一次發送和接收動作來收集跟蹤標識符和時間戳。
在Dapper這篇論文中,Trace和Span是兩個很重要的名詞。我們使用Trace表示對一次請求完整調用鏈的跟蹤,而將兩個服務例如上面的服務A和服務B的請求/響應過程叫做一次Span,trace是通過span來體現的, 通過一句話總結,我們可以將一次trace,看成是span的有向圖,而這個有向圖的邊即為span。而分布式跟蹤系統要做的,就是記錄每次發送和接受動作的標識符和時間戳,將一次請求涉及到的所有服務串聯起來,只有這樣才能搞清楚一次請求的完整調用鏈。
2. 架構圖
第一種:直接將數據寫入存儲
第二種:使用Kafka作為緩沖
在上圖,我們看到Jaeger系統中:黃色部分是我們的應用程序代碼;紅色部門表示instrument操作,即把我們應用程序與jaeger-client裝載起來,從而開始了應用程序到Jaeger的的數據交互操作。將該部分放大來看,我們可以參考下圖,了解詳細的數據交互方式:
Jaeger有5個模塊元素,列表如下,接下來我們來分別解釋這五個模塊的作用:
1.Jaeger-client
2.Agent
3.Collector
4.Data Store
5.UI
1. Jaeger-client
是Jaeger客戶端代碼庫,便於不同語言的項目來介入到Jaeger中,當我們的應用程序裝載上之后,client會負責收集並發送數據到Agent。當前Jaeger的SDK支持有如下:
--官方
1.Go
2.Java
3.Node
4.Python
5.C++
--非官方
1.PHP
3.Others
- 實現了OpenTracing API接口
- 當應用建立Span並發出請求到下游的服務時,它會附帶跟蹤信息(Trace ID, Span ID, baggage)。其他信息比如請求的名字,請求的參數,日志不會發給下游服務,而會被取樣並異步的通過Jaeger-client發送到Jaeger-agent。
- 因為創建跟蹤信息的代價很小,跟蹤功能是默認開啟的。
- 雖然跟蹤功能是默認開啟,但只有一部分的跟蹤會被記錄下來。默認比例是0.1%的取樣
這里再次放上這張圖片結合上面的幾點方便理解收集發送數據的操作:
2. Jaeger-agent:
是Jaeger客戶端代理,jaeger的agent,是一個監聽在 UDP 端口上接收 span 數據的網絡守護進程。 如同大多數分布式系統都擁有一個Agent一樣,Jaeger的Agent有以下幾類特點:
- agent收集並匯聚這些span信息到collector;
- agent的被設計成一個基礎組件,旨在作為基礎架構組件部署到所有宿主機;
- agent將client library 和 collector 解耦,為 client library 屏蔽了路由和發現 collector 的細節;
總結如下:
- 與應用運行在同一個機器里
- 負責接受從客戶端通過UDP發來的Trace/Span信息
- 批量上傳到Jaeger收集器
3. Jaeger-collector
collector,顧名思義,從agent收集traces信息,並通過處理管道處理他們,再寫入后端存儲(backends)。
當前的collector工作主要是管理trace,建立索引,執行相關轉換,並最終存儲它們。
Collector中運行着sampling邏輯,根據我們設定的sampling方式對數據進行收集和處理。
總結如下:
- 接受從agent發來的Trace/Span信息
- 進行信息校驗,索引和存儲到后台的數據庫
4. DB
即數據存儲。Jaeger的存儲是一個可插拔的組件,目前支持Cassandra,Elasticsearch和Kafka(當然也支持純內存方式,但是不適用於生產環境)
5. Query & UI
數據查詢與前端界面展示。Query查詢是一種從存儲中檢索trace,並提供UI以顯示它們的服務。上圖中就展示了一次Trace的數據流向,作為一次系統作用的數據傳播/執行圖,即可以在Jaeger UI上展示出來。
這里放兩張UI圖:
jaeger ui 首頁:
jaeger 查詢結果:
三、關於采樣率
分布式追蹤系統本身也會造成一定的性能低損耗,如果完整記錄每次請求,對於生產環境可能會有極大的性能損耗,一般需要進行采樣設置。
當前支持四種采樣率設置:
-
固定采樣(sampler.type=const)sampler.param=1 全采樣, sampler.param=0 不采樣;
-
按百分比采樣(sampler.type=probabilistic)sampler.param=0.1 則隨機采十分之一的樣本;
-
采樣速度限制(sampler.type=ratelimiting)sampler.param=2.0 每秒采樣兩個traces;
-
動態獲取采樣率 (sampler.type=remote) 這個是默認配置,可以通過配置從 Agent 中獲取采樣率的動態設置。
自適應采樣(Adaptive Sampling)也已經在開發計划中。