前言
傳統(tǒng)的單體服務(wù)通過日志和性能監(jiān)控為我們的系統(tǒng)提供了良好的觀測(cè)手段,隨著服務(wù)之間的交互越來越多,越來越復(fù)雜,這種“各自為政”的策略將使我們看不到整體的關(guān)聯(lián)性。為了提高系統(tǒng)的可見性觀察,分布式鏈路追蹤被提了出來,并迅速發(fā)展。
背景
分布式體系的構(gòu)建是以“拆”為核心,其目標(biāo)是職責(zé)分明、高度自治。不同的模塊甚至?xí)刹煌膱F(tuán)隊(duì)負(fù)責(zé),用不同的語言編寫。當(dāng)我們想要組合這些服務(wù),對(duì)外提供統(tǒng)一功能時(shí),我們還需要考慮它的一個(gè)可觀察性。比如,請(qǐng)求里的服務(wù)依賴有哪些,各個(gè)節(jié)點(diǎn)的耗時(shí)是怎么樣的,瓶頸在哪里等。
像這種涉及上下文請(qǐng)求、端到端的流向監(jiān)控便是分布式鏈路追蹤了。當(dāng)我們的系統(tǒng)出現(xiàn)瓶頸或者故障時(shí),就能根據(jù)收集到的信息快速定位問題、解決問題。這也是它的價(jià)值所在。
不過,在面對(duì)一個(gè)復(fù)雜的系統(tǒng)時(shí),分布式鏈路追蹤考慮的點(diǎn)就有很多了,主要有以下幾點(diǎn):
- 透明性:各個(gè)模塊可能是由不同語言編寫,我們需要考慮接入成本,最好是無需改動(dòng)什么,便可以完成接入。
- 可靠性:上下文的數(shù)據(jù)收集是 24 小時(shí)持續(xù)進(jìn)行的,分布式鏈路追蹤需要考慮穩(wěn)定性及規(guī)模拓展。
- 獨(dú)立性:監(jiān)控是輔助行為,即使鏈路追蹤繁忙或失敗,也不當(dāng)影響業(yè)務(wù)的運(yùn)行。
當(dāng)然,最核心的設(shè)計(jì)還是在于如何將各個(gè)節(jié)點(diǎn)的統(tǒng)計(jì)信息串聯(lián)起來,并進(jìn)行分析展示。
解決方案
從大的層面來講,分布式追蹤其實(shí)跟日志收集優(yōu)點(diǎn)類似。比如需要在每個(gè)節(jié)點(diǎn)記錄性能數(shù)據(jù),然后由專門的收集組件將數(shù)據(jù)發(fā)送到核心組件。核心組件將數(shù)據(jù)進(jìn)行存儲(chǔ)并進(jìn)行一個(gè)關(guān)聯(lián)關(guān)系的添加,畢竟一條完整的鏈路數(shù)據(jù)是來源于各個(gè)服務(wù)的。當(dāng)數(shù)據(jù)分析完后,我們就可以在 Dashboard 里搜索結(jié)果了。
像現(xiàn)在主流的分布式鏈路追蹤產(chǎn)品:Jaeger 就是這么設(shè)計(jì)的。不過,Jaeger 也是受 Google 的 Dapper 啟發(fā)設(shè)計(jì)的。Dapper 是最早的跟分布式鏈路有關(guān)的實(shí)施產(chǎn)品,并有一篇論文: Dapper, a Large-Scale Distributed Systems Tracing Infrastructure ,算是分布式鏈路追蹤系統(tǒng)的鼻祖了,有興趣的小伙伴們可以自行搜索查看。
當(dāng)分布式鏈路的產(chǎn)品越來越多時(shí),統(tǒng)一標(biāo)準(zhǔn)便成了很多人的心聲,畢竟兼容處理也是很麻煩的。后面 CNCF(云原生計(jì)算基金會(huì))推出了 OpenTracing 項(xiàng)目。OpenTracing 是與平臺(tái)廠商無關(guān)的鏈路解決方案。它并不提供具體的實(shí)現(xiàn)代碼,僅僅只是制定規(guī)范,讓接入它的人能有個(gè)一致的協(xié)議。
當(dāng)前根據(jù)這個(gè)標(biāo)準(zhǔn)實(shí)現(xiàn)的產(chǎn)品比較多,像剛剛提及的 Jaeger,還有 Apache 的 Skywalking 等。今天我們來詳細(xì)看下 OpenTracing 的總體設(shè)計(jì),以及它的實(shí)現(xiàn)產(chǎn)品:Jaeger?;蛟S以后我們也可以根據(jù) OpenTracing 標(biāo)準(zhǔn)來實(shí)現(xiàn)一款屬于自己的分布式鏈路追蹤產(chǎn)品。
概念
Trace & Span
在廣義上來講,我們將某一次請(qǐng)求的完整鏈路抽象成了 Trace 概念。一個(gè) Trace 就代表了一次流程的執(zhí)行過程。它實(shí)際上就是一個(gè)有向無環(huán)圖:
[圖片上傳失敗...(image-911300-1649041240605)]
為了能清晰的描述鏈路里的上下文請(qǐng)求,我們將這些關(guān)鍵路徑抽象為了一個(gè)個(gè)的 Span,每個(gè) Span 是一個(gè)基本單元,具有操作名稱、操作的開始、持續(xù)時(shí)間。通過各個(gè) Span 的嵌套和排序,我們就可以建立起因果關(guān)系模型了。
[圖片上傳失敗...(image-e372f6-1649041240605)]
這種模型能讓我們更好的理解服務(wù)的層次關(guān)系、執(zhí)行的上下文時(shí)間等,有助于我們快速的發(fā)現(xiàn)系統(tǒng)的調(diào)用情況。
[圖片上傳失敗...(image-66eda2-1649041240605)]
其中,Span 除了上面的基本屬性,還擁有其他關(guān)聯(lián)的特性字段:
- Span Tag,Span 標(biāo)簽集合。
- Span Log,屬于一組 Span 的日志集合
- SpanContext:Span 上下文對(duì)象,用來描述與其他 Span 的關(guān)系,有 ChildOf(父子) 和 FollowsFrom(跟隨)。SpanContext 的信息添加和獲取分別是通過 Injected 和 Extracted 某個(gè) Carrier (載體)來實(shí)現(xiàn)的。
功能模塊
當(dāng)數(shù)據(jù)模型出來后,我們就可以定義接口了。當(dāng)然,由于 OpenTracing 并不負(fù)責(zé)具體的實(shí)現(xiàn),所以這里的接口更多是一種功能模塊的描述,然后通過類似偽代碼的形式來公開。此處并不具體描述這些接口的傳參、返回格式,主要來看看有哪些功能模塊。
首先是跨進(jìn)程的邊界信息傳遞。在這里,我們會(huì)涉及到 Span 的創(chuàng)建,SpanContext 的 carrier(載體)注入(Inject),以及從 carrier(載體)的提取(Extract)。關(guān)于邊界的信息傳遞,我們可以通過埋點(diǎn)來統(tǒng)一處理,比如 Request 和 Response 的攔截器機(jī)制。
接著是 Span 生命周期的管理,上面創(chuàng)建出 Span 后,我們就需要有一個(gè)明確的完成時(shí)間來結(jié)束 Span。當(dāng)然,如果 Span 需要有什么特性標(biāo)注,那么我們也可以在這個(gè)功能模塊里實(shí)現(xiàn),比如 Span 的 Tag 設(shè)置。
最后是 SpanContext,由于 SpanContext 關(guān)聯(lián)了上下文,所以它比較關(guān)鍵,在 OpenTracing 里它更多的是一個(gè)概念,具體需要哪些功能可以由開發(fā)者自己實(shí)現(xiàn)一套。只要包含了上面的 Inject(注入)和 Extract(提?。┘纯伞?/p>
Jaeger
上面的標(biāo)準(zhǔn)為我們定義了功能模塊及模型接口。那么我們圍繞這些結(jié)構(gòu)和 API 也就能實(shí)現(xiàn)具體的產(chǎn)品了。Uber 出品的 Jaeger 就是其中的一個(gè)。它主要實(shí)現(xiàn)了 OpenTracing 并提供以下功能:
- 分布式上下文傳播
- 分布式事務(wù)監(jiān)控
- 結(jié)構(gòu)化的根本原因分析
- 服務(wù)依賴關(guān)系分析
- 性能分析、延遲分析
在進(jìn)行具體實(shí)現(xiàn)的時(shí)候,Jaeger 為了能提供更好的拓展性,進(jìn)行了組件的拆分,每個(gè)組件都支持單獨(dú)部署,這也符合了微服務(wù)的設(shè)計(jì)理念。主要的組件如下:
- jaeger-client:Jaeger 客戶端,根據(jù) OpenTracing 的標(biāo)準(zhǔn)實(shí)現(xiàn)了對(duì)應(yīng)的 API。例如當(dāng)發(fā)生 RPC 等跨服務(wù)調(diào)用時(shí),此時(shí)會(huì)觸發(fā) client 的 span 創(chuàng)建,并確定好 SpanContext 關(guān)系。
- jaeger-agent:本地存儲(chǔ) client 的 Span 信息,隨后會(huì)將數(shù)據(jù)批量的上傳到 Jaeger Collector。
- jaeger-collector:存儲(chǔ) agent 傳來的數(shù)據(jù),會(huì)為其建立索引并轉(zhuǎn)換。
- jaeger-query:jaeger 的 dashboard 數(shù)據(jù)展示。
它的總體架構(gòu)圖如下:
[圖片上傳失敗...(image-3cc8fd-1649041240605)]
最終,我們將看到如下的查詢 UI:
[圖片上傳失敗...(image-1358fa-1649041240605)]
[圖片上傳失敗...(image-dfc027-1649041240605)]
可以看到,服務(wù)依賴、耗時(shí)分析等 Jaeger 都幫我們通過 web UI 呈現(xiàn)出來了!
總結(jié)
本文主要介紹了分布式鏈路追蹤的標(biāo)準(zhǔn)規(guī)范:OpenTracing 以及它的實(shí)現(xiàn):Jaeger。事實(shí)證明,在越復(fù)雜的系統(tǒng)里,我們?cè)揭M可能的利用這些出色的組件,對(duì)其監(jiān)控起來。只有提高系統(tǒng)的可見性,我們才不至于在問題出現(xiàn)的時(shí)候手忙腳亂。
參考
感興趣的朋友可以搜一搜公眾號(hào)「 閱新技術(shù) 」,關(guān)注更多的推送文章。
可以的話,就順便點(diǎn)個(gè)贊、留個(gè)言、分享下,感謝各位支持!
閱新技術(shù),閱讀更多的新知識(shí)。