1. 什么是鏈路追蹤?分布式系統(tǒng)如何實(shí)現(xiàn)鏈路追蹤?

        共 4772字,需瀏覽 10分鐘

         ·

        2020-11-17 23:37

        公眾號(hào)關(guān)注杰哥的IT之旅”,
        選擇“星標(biāo)”,重磅干貨,第一時(shí)間送達(dá)!

        在分布式系統(tǒng),尤其是微服務(wù)系統(tǒng)中,一次外部請求往往需要內(nèi)部多個(gè)模塊,多個(gè)中間件,多臺(tái)機(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á)哪臺(tái)機(jī)器上、每個(gè)服務(wù)節(jié)點(diǎn)的請求狀態(tài)等等。

        鏈路追蹤的原理

        衡量一個(gè)接口,我們一般會(huì)看三個(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)慢慢會(huì)朝微服務(wù)架構(gòu)發(fā)展,如下:

        在微服務(wù)架構(gòu)下,當(dāng)有用戶反饋某個(gè)頁面很慢時(shí),雖然我們知道這個(gè)請求可能的調(diào)用鏈?zhǔn)?A -----> C -----> B -----> D,但服務(wù)這么多,而且每個(gè)服務(wù)都有好幾臺(tái)機(jī)器,怎么知道問題具體出在哪個(gè)服務(wù)?哪臺(tái)機(jī)器呢?

        這也是微服務(wù)這種架構(gòu)下的幾個(gè)痛點(diǎn):

        1、排查問題難度大,周期長
        2、特定場景難復(fù)現(xiàn)
        3、系統(tǒng)性能瓶頸分析較難

        分布式調(diào)用鏈就是為了解決以上幾個(gè)問題而生,它主要的作用如下:

        1、自動(dòng)采取數(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è)輕量級(jí)的標(biāo)準(zhǔn)化層,它位于應(yīng)用程序/類庫和追蹤或日志分析程序之間。它的出現(xiàn)是為了解決不同的分布式追蹤系統(tǒng) API 不兼容的問題。

        OpenTracing 通過提供與平臺(tái)和廠商無關(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)識(shí)。內(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)該會(huì)更好理解一些。

        理解了這三個(gè)概念,接下來我們就看看分布式追蹤系統(tǒng)是如何采集圖中的微服務(wù)調(diào)用鏈。

        我們可以看到底層有一個(gè) Collector 一直在默默無聞地收集數(shù)據(jù),那么每一次調(diào)用 Collector 會(huì)收集哪些信息呢。

        1、全局 trace_id:這是顯然的,這樣才能把每一個(gè)子調(diào)用與最初的請求關(guān)聯(lián)起來
        2、span_id: 圖中的 0,1,1.1,2,這樣就能標(biāo)識(shí)是哪一個(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、怎么自動(dòng)采集 span 數(shù)據(jù):自動(dòng)采集,對業(yè)務(wù)代碼無侵入
        2、如何跨進(jìn)程傳遞 context
        3、traceId 如何保證全局唯一
        4、請求量這么多采集會(huì)不會(huì)影響性能

        接下來,我們來看看鏈路追蹤系統(tǒng) SkyWalking 是如何解決以上四個(gè)問題的。

        鏈路追蹤系統(tǒng)SkyWalking的原理

        1、怎么自動(dòng)采集 span 數(shù)據(jù)

        SkyWalking 采用了插件化 + javaagent 的形式來實(shí)現(xiàn)了 span 數(shù)據(jù)的自動(dòng)采集,這樣可以做到對代碼的無侵入性。插件化意味著可插拔,擴(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ā)號(hào)器,每次請求都要先請求一下發(fā)號(hào)器,會(huì)有一次網(wǎng)絡(luò)調(diào)用的開銷。所以 SkyWalking 最終采用了本地生成 ID 的方式,它采用了大名鼎鼎的 snowflow 算法,性能很高。

        不過 snowflake 算法有一個(gè)眾所周知的問題:時(shí)間回?fù)?/strong>,這個(gè)問題可能會(huì)導(dǎo)致生成的 id 重復(fù)。那么 SkyWalking 是如何解決時(shí)間回?fù)軉栴}的呢。

        每生成一個(gè) id,都會(huì)記錄一下生成 id 的時(shí)間(lastTimestamp),如果發(fā)現(xiàn)當(dāng)前時(shí)間比上一次生成 id 的時(shí)間(lastTimestamp)還小,那說明發(fā)生了時(shí)間回?fù)?,此時(shí)會(huì)生成一個(gè)隨機(jī)數(shù)來作為 traceId。這里可能就有同學(xué)要較真了,可能會(huì)覺得生成的這個(gè)隨機(jī)數(shù)也會(huì)和已生成的全局 id 重復(fù),是否再加一層校驗(yàn)會(huì)好點(diǎn)。

        這里要說一下系統(tǒng)設(shè)計(jì)上的方案取舍問題了,首先如果針對產(chǎn)生的這個(gè)隨機(jī)數(shù)作唯一性校驗(yàn)無疑會(huì)多一層調(diào)用,會(huì)有一定的性能損耗,但其實(shí)時(shí)間回?fù)馨l(fā)生的概率很小(發(fā)生之后由于機(jī)器時(shí)間紊亂,業(yè)務(wù)會(huì)受到很大影響,所以機(jī)器時(shí)間的調(diào)整必然要慎之又慎),再加上生成的隨機(jī)數(shù)重合的概率也很小,綜合考慮這里確實(shí)沒有必要再加一層全局唯一性校驗(yàn)。對于技術(shù)方案的選型,一定要避免過度設(shè)計(jì),過猶不及。

        4、請求量這么多,全部采集會(huì)不會(huì)影響性能?

        如果對每個(gè)請求調(diào)用都采集,那毫無疑問數(shù)據(jù)量會(huì)非常大,但反過來想一下,是否真的有必要對每個(gè)請求都采集呢?其實(shí)沒有必要,我們可以設(shè)置采樣頻率,只采樣部分?jǐn)?shù)據(jù),SkyWalking 默認(rèn)設(shè)置了 3 秒采樣 3 次,其余請求不采樣,如圖所示:

        這樣的采樣頻率其實(shí)足夠我們分析組件的性能了,按 3 秒采樣 3 次,這樣的頻率來采樣數(shù)據(jù)會(huì)有啥問題呢。理想情況下,每個(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)用情況很可能是下圖這樣:

        這樣的話就會(huì)導(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),將其存儲(chǔ)到 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ī)則手動(dòng)寫一個(gè)即可,新實(shí)現(xiàn)的插件對代碼無入侵。

        以上雖然主要以SkyWalking為例來介紹鏈路追蹤系統(tǒng),但是并不是說其他鏈路追蹤系統(tǒng)一點(diǎn)不適用。具體選擇什么樣的,大家可按實(shí)際場景靈活選擇。

        作者:猿話?

        來源:https://www.toutiao.com/i6884571378981274123/


        如果您覺得這篇文章對您有點(diǎn)用的話,麻煩您為本文來個(gè)四連:轉(zhuǎn)發(fā)分享、點(diǎn)贊、點(diǎn)在看、留言,因?yàn)檫@將是我寫作與分享更多優(yōu)質(zhì)文章的最強(qiáng)動(dòng)力!

        本公眾號(hào)全部博文已整理成一個(gè)目錄,請?jiān)诠娞?hào)后臺(tái)回復(fù)「m」獲??!

        推薦閱讀:
        1、成為架構(gòu)師,必須掌握 10 種常見的架構(gòu)模式!
        2、程序員必知的 7 種軟件架構(gòu)模式
        3、一文讀懂「分布式架構(gòu)」
        4、Linux 經(jīng)典的幾款收包引擎
        5、最全 VxLAN 知識(shí)詳解
        6、什么是堡壘機(jī)?為什么需要堡壘機(jī)?
        關(guān)注微信公眾號(hào)「杰哥的IT之旅」,后臺(tái)回復(fù)「1024」查看更多內(nèi)容,回復(fù)「加群備注:地區(qū)-職業(yè)方向-昵稱?即可加入讀者交流群。

        點(diǎn)個(gè)[在看],是對杰哥最大的支持!
        瀏覽 44
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 天天操天天操天天干 | 日本一级婬片免费放 | www.99超碰 | 成人视频在线观看视频 | 热久久av |