什么是鏈路追蹤?
鏈路追蹤的原理
鏈路追蹤系統(tǒng)SkyWalking的原理
SkyWalking 的基礎(chǔ)架構(gòu)
SkyWalking 的性能如何
在分布式系統(tǒng),尤其是微服務(wù)系統(tǒng)中,一次外部請求往往需要內(nèi)部多個(gè)模塊,多個(gè)中間件,多臺機(jī)器的相互調(diào)用才能完成。在這一系列的調(diào)用中,可能有些是串行的,而有些是并行的。在這種情況下,我們?nèi)绾尾拍艽_定這整個(gè)請求調(diào)用了哪些應(yīng)用?哪些模塊?哪些節(jié)點(diǎn)?以及它們的先后順序和各部分的性能如何呢?
這就是涉及到鏈路追蹤。
什么是鏈路追蹤?
鏈路追蹤是分布式系統(tǒng)下的一個(gè)概念,它的目的就是要解決上面所提出的問題,也就是將一次分布式請求還原成調(diào)用鏈路,將一次分布式請求的調(diào)用情況集中展示,比如,各個(gè)服務(wù)節(jié)點(diǎn)上的耗時(shí)、請求具體到達(dá)哪臺機(jī)器上、每個(gè)服務(wù)節(jié)點(diǎn)的請求狀態(tài)等等。
基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
鏈路追蹤的原理
衡量一個(gè)接口,我們一般會看三個(gè)指標(biāo):
1、接口的 RT(Route-Target)你怎么知道?2、接口是否有異常響應(yīng)?3、接口請求慢在哪里?
1、單體架構(gòu)時(shí)代
在創(chuàng)業(yè)初期,我們的系統(tǒng)一般是單體架構(gòu),如下:
對于單體架構(gòu),我們可以使用 AOP(切面編程)來統(tǒng)計(jì)這三個(gè)指標(biāo),如下:
使用 AOP(切面編程),對原本的邏輯代碼侵入更少,我們只需要在調(diào)用具體的業(yè)務(wù)邏輯前后分別打印一下時(shí)間即可計(jì)算出整體的調(diào)用時(shí)間。另外,使用 AOP(切面編程)來捕獲異常也可知道是哪里的調(diào)用導(dǎo)致的異常。
2、微服務(wù)架構(gòu)
隨著業(yè)務(wù)的快速發(fā)展,單體架構(gòu)越來越不能滿足需要,我們的系統(tǒng)慢慢會朝微服務(wù)架構(gòu)發(fā)展,如下:
在微服務(wù)架構(gòu)下,當(dāng)有用戶反饋某個(gè)頁面很慢時(shí),雖然我們知道這個(gè)請求可能的調(diào)用鏈?zhǔn)?A -----> C -----> B -----> D,但服務(wù)這么多,而且每個(gè)服務(wù)都有好幾臺機(jī)器,怎么知道問題具體出在哪個(gè)服務(wù)?哪臺機(jī)器呢?
這也是微服務(wù)這種架構(gòu)下的幾個(gè)痛點(diǎn):
1、排查問題難度大,周期長2、特定場景難復(fù)現(xiàn)3、系統(tǒng)性能瓶頸分析較難
分布式調(diào)用鏈就是為了解決以上幾個(gè)問題而生,它主要的作用如下:
1、自動采取數(shù)據(jù)2、分析數(shù)據(jù),產(chǎn)生完整調(diào)用鏈:有了請求的完整調(diào)用鏈,問題有很大概率可復(fù)現(xiàn)3、數(shù)據(jù)可視化:每個(gè)組件的性能可視化,能幫助我們很好地定位系統(tǒng)的瓶頸,及時(shí)找出問題所在
通過分布式追蹤系統(tǒng),我們能很好地定位請求的每條具體請求鏈路,從而輕易地實(shí)現(xiàn)請求鏈路追蹤,進(jìn)而定位和分析每個(gè)模塊的性能瓶頸。
3、分布式調(diào)用鏈標(biāo)準(zhǔn)(OpenTracing)
OpenTracing 是一個(gè)輕量級的標(biāo)準(zhǔn)化層,它位于應(yīng)用程序/類庫和追蹤或日志分析程序之間。它的出現(xiàn)是為了解決不同的分布式追蹤系統(tǒng) API 不兼容的問題。
OpenTracing 通過提供與平臺和廠商無關(guān)的 API,使得開發(fā)人員能夠方便地添加追蹤系統(tǒng),就像單體架構(gòu)下的AOP(切面編程)一樣。
說到這里,大家是否想過 Java 中類似的實(shí)現(xiàn)?還記得 JDBC 吧?JDBC 就是通過提供一套標(biāo)準(zhǔn)的接口讓各個(gè)廠商去實(shí)現(xiàn),程序員即可面對接口編程,不用關(guān)心具體的實(shí)現(xiàn)。這里的接口其實(shí)就是標(biāo)準(zhǔn)。所以,制定一套標(biāo)準(zhǔn)非常重要,可以實(shí)現(xiàn)組件的可插拔。
OpenTracing 的數(shù)據(jù)模型,主要有以下三個(gè):
Trace:一個(gè)完整請求鏈路
Span:一次調(diào)用過程(需要有開始時(shí)間和結(jié)束時(shí)間)
SpanContext:Trace 的全局上下文信息,如里面有traceId
為了讓大家更好地理解這三個(gè)概念,我特意畫了一張圖:
如圖所示,一次下單的完整請求就是一個(gè) Trace。TraceId是這個(gè)請求的全局標(biāo)識。內(nèi)部的每一次調(diào)用就稱為一個(gè) Span,每個(gè) Span 都要帶上全局的 TraceId,這樣才可把全局 TraceId 與每個(gè)調(diào)用關(guān)聯(lián)起來。這個(gè) TraceId 是通過 SpanContext 傳輸?shù)?,既然要傳輸,顯然都要遵循協(xié)議來調(diào)用。如圖所示,如果我們把傳輸協(xié)議比作車,把 SpanContext 比作貨,把 Span 比作路應(yīng)該會更好理解一些。
理解了這三個(gè)概念,接下來我們就看看分布式追蹤系統(tǒng)是如何采集圖中的微服務(wù)調(diào)用鏈。
我們可以看到底層有一個(gè) Collector 一直在默默無聞地收集數(shù)據(jù),那么每一次調(diào)用 Collector 會收集哪些信息呢。
1、全局 trace_id:這是顯然的,這樣才能把每一個(gè)子調(diào)用與最初的請求關(guān)聯(lián)起來2、span_id: 圖中的 0,1,1.1,2,這樣就能標(biāo)識是哪一個(gè)調(diào)用3、parent_span_id:比如 b 調(diào)用 d 的 span_id 是 1.1,那么它的 parent_span_id 即為 a 調(diào)用 b 的 span_id 即 1,這樣才能把兩個(gè)緊鄰的調(diào)用關(guān)聯(lián)起來。
有了這些信息,Collector 收集的每次調(diào)用的信息如下:
根據(jù)這些圖表信息顯然可以據(jù)此來畫出調(diào)用鏈的可視化視圖如下:
于是一個(gè)完整的分布式追蹤系統(tǒng)就實(shí)現(xiàn)了。
以上實(shí)現(xiàn)看起來確實(shí)簡單,但有以下幾個(gè)問題需要我們仔細(xì)思考一下:
1、怎么自動采集 span 數(shù)據(jù):自動采集,對業(yè)務(wù)代碼無侵入2、如何跨進(jìn)程傳遞 context3、traceId 如何保證全局唯一4、請求量這么多采集會不會影響性能
接下來,我們來看看鏈路追蹤系統(tǒng) SkyWalking 是如何解決以上四個(gè)問題的。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
鏈路追蹤系統(tǒng)SkyWalking的原理
1、怎么自動采集 span 數(shù)據(jù)
SkyWalking 采用了插件化 + javaagent 的形式來實(shí)現(xiàn)了 span 數(shù)據(jù)的自動采集,這樣可以做到對代碼的無侵入性。插件化意味著可插拔,擴(kuò)展性好。如下圖所示:
2、如何跨進(jìn)程傳遞 context
我們知道數(shù)據(jù)一般分為 header 和 body,就像 http 有 header 和 body,RocketMQ 也有 MessageHeader,Message Body。body 一般放著業(yè)務(wù)數(shù)據(jù),所以不宜在 body 中傳遞 context,應(yīng)該在 header 中傳遞 context,如圖所示:
dubbo 中的 attachment 就相當(dāng)于 header,所以我們把 context 放在 attachment 中,這樣就解決了 context 的傳遞問題。
3、traceId 如何保證全局唯一
要保證全局唯一 ,我們可以采用分布式或者本地生成的 ID。使用分布式的話,需要有一個(gè)發(fā)號器,每次請求都要先請求一下發(fā)號器,會有一次網(wǎng)絡(luò)調(diào)用的開銷。所以 SkyWalking 最終采用了本地生成 ID 的方式,它采用了大名鼎鼎的 snowflow 算法,性能很高。
不過 snowflake 算法有一個(gè)眾所周知的問題:時(shí)間回?fù)?,這個(gè)問題可能會導(dǎo)致生成的 id 重復(fù)。那么 SkyWalking 是如何解決時(shí)間回?fù)軉栴}的呢。
每生成一個(gè) id,都會記錄一下生成 id 的時(shí)間(lastTimestamp),如果發(fā)現(xiàn)當(dāng)前時(shí)間比上一次生成 id 的時(shí)間(lastTimestamp)還小,那說明發(fā)生了時(shí)間回?fù)?,此時(shí)會生成一個(gè)隨機(jī)數(shù)來作為 traceId。這里可能就有同學(xué)要較真了,可能會覺得生成的這個(gè)隨機(jī)數(shù)也會和已生成的全局 id 重復(fù),是否再加一層校驗(yàn)會好點(diǎn)。
這里要說一下系統(tǒng)設(shè)計(jì)上的方案取舍問題了,首先如果針對產(chǎn)生的這個(gè)隨機(jī)數(shù)作唯一性校驗(yàn)無疑會多一層調(diào)用,會有一定的性能損耗,但其實(shí)時(shí)間回?fù)馨l(fā)生的概率很小(發(fā)生之后由于機(jī)器時(shí)間紊亂,業(yè)務(wù)會受到很大影響,所以機(jī)器時(shí)間的調(diào)整必然要慎之又慎),再加上生成的隨機(jī)數(shù)重合的概率也很小,綜合考慮這里確實(shí)沒有必要再加一層全局唯一性校驗(yàn)。對于技術(shù)方案的選型,一定要避免過度設(shè)計(jì),過猶不及。
4、請求量這么多,全部采集會不會影響性能?
如果對每個(gè)請求調(diào)用都采集,那毫無疑問數(shù)據(jù)量會非常大,但反過來想一下,是否真的有必要對每個(gè)請求都采集呢?其實(shí)沒有必要,我們可以設(shè)置采樣頻率,只采樣部分?jǐn)?shù)據(jù),SkyWalking 默認(rèn)設(shè)置了 3 秒采樣 3 次,其余請求不采樣,如圖所示:
這樣的采樣頻率其實(shí)足夠我們分析組件的性能了,按 3 秒采樣 3 次,這樣的頻率來采樣數(shù)據(jù)會有啥問題呢。理想情況下,每個(gè)服務(wù)調(diào)用都在同一個(gè)時(shí)間點(diǎn),這樣的話每次都在同一時(shí)間點(diǎn)采樣確實(shí)沒問題。如下圖所示:
但在生產(chǎn)上,每次服務(wù)調(diào)用基本不可能都在同一時(shí)間點(diǎn)調(diào)用,因?yàn)槠陂g有網(wǎng)絡(luò)調(diào)用延時(shí)等,實(shí)際調(diào)用情況很可能是下圖這樣:
這樣的話就會導(dǎo)致某些調(diào)用在服務(wù) A 上被采樣了,在服務(wù) B,C 上不被采樣,也就沒法分析調(diào)用鏈的性能。
那么 SkyWalking 是如何解決的呢?
它是這樣解決的:如果上游有攜帶 Context 過來(說明上游采樣了),則下游將強(qiáng)制采集數(shù)據(jù),這樣可以保證鏈路完整。
SkyWalking 的基礎(chǔ)架構(gòu)
SkyWalking 的基礎(chǔ)如下架構(gòu),可以說幾乎所有的的分布式調(diào)用都是由以下幾個(gè)組件組成的。
首先當(dāng)然是節(jié)點(diǎn)數(shù)據(jù)的定時(shí)采樣,采樣后將數(shù)據(jù)定時(shí)上報(bào),將其存儲到 ES, MySQL 等持久化層,有了數(shù)據(jù)自然而然可根據(jù)數(shù)據(jù)做可視化分析。
SkyWalking 的性能如何
如下是官方的測評數(shù)據(jù):
圖中藍(lán)色代表未使用 SkyWalking 的表現(xiàn),橙色代表使用了 SkyWalking 的表現(xiàn),以上是在 TPS 為 5000 的情況下測出的數(shù)據(jù),可以看出,不論是 CPU,內(nèi)存,還是響應(yīng)時(shí)間,使用 SkyWalking 帶來的性能損耗幾乎可以忽略不計(jì)。
接下來我們再來看 SkyWalking 與另一款業(yè)界比較知名的分布式追蹤工具 Zipkin、Pinpoint 的對比(在采樣率為 1 秒 1 個(gè),線程數(shù) 500,請求總數(shù)為 5000 的情況下做的對比)。
可以看到在關(guān)鍵的響應(yīng)時(shí)間上, Zipkin(117ms),PinPoint(201ms)遠(yuǎn)遜于 SkyWalking(22ms)!從性能損耗這個(gè)指標(biāo)上看,SkyWalking 完勝!
再看下另一個(gè)指標(biāo):對代碼的侵入性如何。
ZipKin 是需要在應(yīng)用程序中埋點(diǎn)的,對代碼的侵入強(qiáng),而 SkyWalking 采用 javaagent + 插件化這種修改字節(jié)碼的方式可以做到對代碼無任何侵入。除了性能和對代碼的侵入性上 SkyWaking 表現(xiàn)不錯(cuò)外,它還有以下優(yōu)勢幾個(gè)優(yōu)勢:
對多語言的支持,組件豐富:目前其支持 Java、 .Net Core、PHP、NodeJS、Golang、LUA 語言,組件上也支持dubbo, mysql 等常見組件,大部分能滿足我們的需求。
擴(kuò)展性:對于不滿足的插件,我們按照 SkyWalking 的規(guī)則手動寫一個(gè)即可,新實(shí)現(xiàn)的插件對代碼無入侵。
以上雖然主要以SkyWalking為例來介紹鏈路追蹤系統(tǒng),但是并不是說其他鏈路追蹤系統(tǒng)一點(diǎn)不適用。具體選擇什么樣的,大家可按實(shí)際場景靈活選擇。
編輯:何安
-
鏈路
+關(guān)注
關(guān)注
1文章
76瀏覽量
14262 -
分布式系統(tǒng)
+關(guān)注
關(guān)注
0文章
147瀏覽量
19635
原文標(biāo)題:什么是鏈路追蹤?分布式系統(tǒng)如何實(shí)現(xiàn)鏈路追蹤?
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
光鏈路實(shí)時(shí)監(jiān)測倒換系統(tǒng)
基于分布式調(diào)用鏈監(jiān)控技術(shù)的全息排查功能
時(shí)鐘抖動對高速鏈路性能的影響
天線的鏈路預(yù)算
系統(tǒng)同步多通道數(shù)字鏈路怎么設(shè)計(jì)
什么是無線鏈路預(yù)算表?
怎么簡化RF信號鏈路的分析?
鏈路聚合,鏈路聚合是什么意思
多鏈路PPP,什么是多鏈路PPP
基于磁鏈追蹤的雙饋風(fēng)力發(fā)電系統(tǒng)低電壓穿越
Apache SkyWalking Client JS Skywalking客戶端JS異常與追蹤庫

配置Skywalking告警

評論