开放分布式追踪(OpenTracing)入门与 Jaeger 实现
摘要:?分布式系統(tǒng)的運(yùn)維挑戰(zhàn) 容器、Serverless 編程方式的誕生極大提升了軟件交付與部署的效率。在架構(gòu)的演化過程中,可以看到兩個(gè)變化: 應(yīng)用架構(gòu)開始從單體系統(tǒng)逐步轉(zhuǎn)變?yōu)槲⒎?wù),其中的業(yè)務(wù)邏輯隨之而來就會(huì)變成微服務(wù)之間的調(diào)用與請(qǐng)求。
點(diǎn)此查看原文:http://click.aliyun.com/m/43363/
分布式系統(tǒng)的運(yùn)維挑戰(zhàn)
容器、Serverless 編程方式的誕生極大提升了軟件交付與部署的效率。在架構(gòu)的演化過程中,可以看到兩個(gè)變化:
- 應(yīng)用架構(gòu)開始從單體系統(tǒng)逐步轉(zhuǎn)變?yōu)槲⒎?wù),其中的業(yè)務(wù)邏輯隨之而來就會(huì)變成微服務(wù)之間的調(diào)用與請(qǐng)求。
- 資源角度來看,傳統(tǒng)服務(wù)器這個(gè)物理單位也逐漸淡化,變成了看不見摸不到的虛擬資源模式。
從以上兩個(gè)變化可以看到這種彈性、標(biāo)準(zhǔn)化的架構(gòu)背后,原先運(yùn)維與診斷的需求也變得越來越復(fù)雜。為了應(yīng)對(duì)這種變化趨勢(shì),誕生一系列面向 DevOps 的診斷與分析系統(tǒng),包括集中式日志系統(tǒng)(Logging),集中式度量系統(tǒng)(Metrics)和分布式追蹤系統(tǒng)(Tracing)。
Logging,Metrics 和 Tracing
Logging,Metrics 和 Tracing 有各自專注的部分。
- Logging - 用于記錄離散的事件。例如,應(yīng)用程序的調(diào)試信息或錯(cuò)誤信息。它是我們?cè)\斷問題的依據(jù)。
- Metrics - 用于記錄可聚合的數(shù)據(jù)。例如,隊(duì)列的當(dāng)前深度可被定義為一個(gè)度量值,在元素入隊(duì)或出隊(duì)時(shí)被更新;HTTP 請(qǐng)求個(gè)數(shù)可被定義為一個(gè)計(jì)數(shù)器,新請(qǐng)求到來時(shí)進(jìn)行累加。
- Tracing - 用于記錄請(qǐng)求范圍內(nèi)的信息。例如,一次遠(yuǎn)程方法調(diào)用的執(zhí)行過程和耗時(shí)。它是我們排查系統(tǒng)性能問題的利器。
這三者也有相互重疊的部分,如下圖所示。
通過上述信息,我們可以對(duì)已有系統(tǒng)進(jìn)行分類。例如,Zipkin 專注于 tracing 領(lǐng)域;Prometheus 開始專注于 metrics,隨著時(shí)間推移可能會(huì)集成更多的 tracing 功能,但不太可能深入 logging 領(lǐng)域; ELK,阿里云日志服務(wù)這樣的系統(tǒng)開始專注于 logging 領(lǐng)域,但同時(shí)也不斷地集成其他領(lǐng)域的特性到系統(tǒng)中來,正向上圖中的圓心靠近。
關(guān)于三者關(guān)系的更詳細(xì)信息可參考?Metrics, tracing, and logging。下面我們重點(diǎn)介紹下 tracing。
Tracing 的誕生
Tracing 是在90年代就已出現(xiàn)的技術(shù)。但真正讓該領(lǐng)域流行起來的還是源于 Google 的一篇論文"Dapper, a Large-Scale Distributed Systems Tracing Infrastructure",而另一篇論文"Uncertainty in Aggregate Estimates from Sampled Distributed Traces"中則包含關(guān)于采樣的更詳細(xì)分析。論文發(fā)表后一批優(yōu)秀的 Tracing 軟件孕育而生,比較流行的有:
- Dapper(Google) : 各 tracer 的基礎(chǔ)
- StackDriver Trace (Google)
- Zipkin(twitter)
- Appdash(golang)
- 鷹眼(taobao)
- 諦聽(盤古,阿里云云產(chǎn)品使用的Trace系統(tǒng))
- 云圖(螞蟻Trace系統(tǒng))
- sTrace(神馬)
- X-ray(aws)
分布式追蹤系統(tǒng)發(fā)展很快,種類繁多,但核心步驟一般有三個(gè):代碼埋點(diǎn),數(shù)據(jù)存儲(chǔ)、查詢展示。
下圖是一個(gè)分布式調(diào)用的例子,客戶端發(fā)起請(qǐng)求,請(qǐng)求首先到達(dá)負(fù)載均衡器,接著經(jīng)過認(rèn)證服務(wù),計(jì)費(fèi)服務(wù),然后請(qǐng)求資源,最后返回結(jié)果。
數(shù)據(jù)被采集存儲(chǔ)后,分布式追蹤系統(tǒng)一般會(huì)選擇使用包含時(shí)間軸的時(shí)序圖來呈現(xiàn)這個(gè) Trace。
但在數(shù)據(jù)采集過程中,由于需要侵入用戶代碼,并且不同系統(tǒng)的 API 并不兼容,這就導(dǎo)致了如果您希望切換追蹤系統(tǒng),往往會(huì)帶來較大改動(dòng)。
OpenTracing
為了解決不同的分布式追蹤系統(tǒng) API 不兼容的問題,誕生了?OpenTracing?規(guī)范。
OpenTracing 是一個(gè)輕量級(jí)的標(biāo)準(zhǔn)化層,它位于應(yīng)用程序/類庫和追蹤或日志分析程序之間。
OpenTracing 的優(yōu)勢(shì)
- OpenTracing 已進(jìn)入 CNCF,正在為全球的分布式追蹤,提供統(tǒng)一的概念和數(shù)據(jù)標(biāo)準(zhǔn)。
- OpenTracing 通過提供平臺(tái)無關(guān)、廠商無關(guān)的 API,使得開發(fā)人員能夠方便的添加(或更換)追蹤系統(tǒng)的實(shí)現(xiàn)。
OpenTracing 數(shù)據(jù)模型
OpenTracing 中的?Trace(調(diào)用鏈)通過歸屬于此調(diào)用鏈的?Span?來隱性的定義。
特別說明,一條?Trace(調(diào)用鏈)可以被認(rèn)為是一個(gè)由多個(gè)?Span?組成的有向無環(huán)圖(DAG圖),Span?與?Span?的關(guān)系被命名為?References。
例如:下面的示例?Trace?就是由8個(gè)?Span?組成:
單個(gè) Trace 中,span 間的因果關(guān)系[Span A] ←←←(the root span)|+------+------+| |[Span B] [Span C] ←←←(Span C 是 Span A 的孩子節(jié)點(diǎn), ChildOf)| |[Span D] +---+-------+| |[Span E] [Span F] >>> [Span G] >>> [Span H]↑↑↑(Span G 在 Span F 后被調(diào)用, FollowsFrom)有些時(shí)候,使用下面這種,基于時(shí)間軸的時(shí)序圖可以更好的展現(xiàn)?Trace(調(diào)用鏈):
單個(gè) Trace 中,span 間的時(shí)間關(guān)系––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time[Span A···················································][Span B··············································][Span D··········································][Span C········································][Span E·······] [Span F··] [Span G··] [Span H··]每個(gè)?Span?包含以下的狀態(tài):(譯者注:由于這些狀態(tài)會(huì)反映在 OpenTracing API 中,所以會(huì)保留部分英文說明)
- An operation name,操作名稱
- A start timestamp,起始時(shí)間
- A finish timestamp,結(jié)束時(shí)間
- Span Tag,一組鍵值對(duì)構(gòu)成的 Span 標(biāo)簽集合。鍵值對(duì)中,鍵必須為 string,值可以是字符串,布爾,或者數(shù)字類型。
- Span Log,一組 span 的日志集合。
每次 log 操作包含一個(gè)鍵值對(duì),以及一個(gè)時(shí)間戳。
鍵值對(duì)中,鍵必須為 string,值可以是任意類型。
但是需要注意,不是所有的支持 OpenTracing 的 Tracer,都需要支持所有的值類型。
- SpanContext,Span 上下文對(duì)象 (下面會(huì)詳細(xì)說明)
- References(Span間關(guān)系),相關(guān)的零個(gè)或者多個(gè) Span(Span?間通過?SpanContext?建立這種關(guān)系)
每一個(gè)?SpanContext?包含以下狀態(tài):
- 任何一個(gè) OpenTracing 的實(shí)現(xiàn),都需要將當(dāng)前調(diào)用鏈的狀態(tài)(例如:trace 和 span 的 id),依賴一個(gè)獨(dú)特的 Span 去跨進(jìn)程邊界傳輸
- Baggage Items,Trace 的隨行數(shù)據(jù),是一個(gè)鍵值對(duì)集合,它存在于 trace 中,也需要跨進(jìn)程邊界傳輸
更多關(guān)于 OpenTracing 數(shù)據(jù)模型的知識(shí),請(qǐng)參考?OpenTracing語義標(biāo)準(zhǔn)。
OpenTracing 實(shí)現(xiàn)
這篇文檔列出了所有 OpenTracing 實(shí)現(xiàn)。在這些實(shí)現(xiàn)中,比較流行的為?Jaeger?和?Zipkin。
Jaeger
Jaeger?是 Uber 推出的一款開源分布式追蹤系統(tǒng),兼容 OpenTracing API。
Jaeger 架構(gòu)
如上圖所示,Jaeger 主要由以下幾部分組成。
- Jaeger Client - 為不同語言實(shí)現(xiàn)了符合?OpenTracing?標(biāo)準(zhǔn)的 SDK。應(yīng)用程序通過 API 寫入數(shù)據(jù),client library 把 trace 信息按照應(yīng)用程序指定的采樣策略傳遞給 jaeger-agent。
- Agent - 它是一個(gè)監(jiān)聽在 UDP 端口上接收 span 數(shù)據(jù)的網(wǎng)絡(luò)守護(hù)進(jìn)程,它會(huì)將數(shù)據(jù)批量發(fā)送給 collector。它被設(shè)計(jì)成一個(gè)基礎(chǔ)組件,部署到所有的宿主機(jī)上。Agent 將 client library 和 collector 解耦,為 client library 屏蔽了路由和發(fā)現(xiàn) collector 的細(xì)節(jié)。
- Collector - 接收 jaeger-agent 發(fā)送來的數(shù)據(jù),然后將數(shù)據(jù)寫入后端存儲(chǔ)。Collector 被設(shè)計(jì)成無狀態(tài)的組件,因此您可以同時(shí)運(yùn)行任意數(shù)量的 jaeger-collector。
- Data Store - 后端存儲(chǔ)被設(shè)計(jì)成一個(gè)可插拔的組件,支持將數(shù)據(jù)寫入 cassandra、elastic search。
- Query - 接收查詢請(qǐng)求,然后從后端存儲(chǔ)系統(tǒng)中檢索 trace 并通過 UI 進(jìn)行展示。Query 是無狀態(tài)的,您可以啟動(dòng)多個(gè)實(shí)例,把它們部署在 nginx 這樣的負(fù)載均衡器后面。
Jaeger 存在的問題
- 需要架設(shè)并維護(hù)存儲(chǔ)。
- UI比較薄弱,有一些個(gè)性化的分析需求無法快速滿足(例如對(duì)比,統(tǒng)計(jì)延遲分布等)。
Jaeger on Aliyun Log Service
Jaeger on Aliyun Log Service?是基于 Jeager 開發(fā)的分布式追蹤系統(tǒng),支持將采集到的追蹤數(shù)據(jù)持久化到日志服務(wù)中,并通過 Jaeger 的原生接口進(jìn)行查詢和展示。
優(yōu)勢(shì)
- 原生 Jaeger 僅支持將數(shù)據(jù)持久化到 cassandra 和 elasticsearch 中,用戶需要自行維護(hù)后端存儲(chǔ)系統(tǒng)的穩(wěn)定性,調(diào)節(jié)存儲(chǔ)容量。Jaeger on Aliyun Log Service 借助阿里云日志服務(wù)的海量數(shù)據(jù)處理能力,讓您享受 Jaeger 在分布式追蹤領(lǐng)域給您帶來便捷的同時(shí)無需過多關(guān)注后端存儲(chǔ)系統(tǒng)的問題。
- Jaeger UI 部分僅提供查詢、展示 trace 的功能,對(duì)分析問題、排查問題支持不足。使用 Jaeger on Aliyun Log Service,您可以借助日志服務(wù)強(qiáng)大的查詢分析能力,助您更快分析出系統(tǒng)中存在的問題。
- 相對(duì)于 Jaeger 使用 elasticsearch 作為后端存儲(chǔ),使用日志服務(wù)的好處是支持按量付費(fèi),成本僅為 elasticsearch 的13%。參閱自建ELK vs 日志服務(wù)(SLS)全方位對(duì)比
配置步驟
參閱:https://github.com/aliyun/jaeger/blob/master/README_CN.md
使用實(shí)例
HotROD?是由多個(gè)微服務(wù)組成的應(yīng)用程序,它使用了 OpenTracing API 記錄 trace 信息。
下面通過一段視頻向您展示如何使用 Jaeger on Aliyun Log Service 診斷 HotROD 出現(xiàn)的問題。視頻包含以下內(nèi)容:
視頻中用到的查詢分析樣例
1. 以分鐘為單位統(tǒng)計(jì)?frontend?服務(wù)的?HTTP GET /dispatch?操作的平均延遲以及請(qǐng)求個(gè)數(shù)。
process.serviceName: "frontend" and operationName: "HTTP GET /dispatch" | select from_unixtime( __time__ - __time__ % 60) as time, truncate(avg(duration)/1000/1000) as avg_duration_ms, count(1) as count group by __time__ - __time__ % 60 order by time desc limit 602. 比較兩條 trace 各個(gè)操作的耗時(shí)
traceID: "trace1" or traceID: "trace2" | select operationName, (max(duration)-min(duration))/1000/1000 as duration_diff_ms group by operationName order by duration_diff_ms desc3. 統(tǒng)計(jì)延遲大于 1.5s 的 trace 的 IP 情況
process.serviceName: "frontend" and operationName: "HTTP GET /dispatch" and duration > 1500000000 | select "process.tags.ip" as IP, truncate(avg(duration)/1000/1000) as avg_duration_ms, count(1) as count group by "process.tags.ip"參考資料
- Jaeger on Aliyun Log Service -?https://github.com/aliyun/jaeger
- OpenTracing 中文文檔 -?https://wu-sheng.gitbooks.io/opentracing-io/content/
- Jaeger -?http://jaeger.readthedocs.io/en/latest/getting_started/
- OpenTracing tutorial -?https://github.com/yurishkuro/opentracing-tutorial
- http://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html
特別感謝
Jaeger on Aliyun Log Service 是基于阿里云MVP?@WPH95?在業(yè)余時(shí)間工作整理而成,感謝 MVP
的杰出貢獻(xiàn)!
識(shí)別以下二維碼,干貨
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的开放分布式追踪(OpenTracing)入门与 Jaeger 实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业如何采用机器学习
- 下一篇: 阿里云正式推出消息队列Kafka:全面融