1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        分布式鏈路追蹤系統(tǒng)原來是這么一回事

        共 7280字,需瀏覽 15分鐘

         ·

        2020-11-19 09:14




        本篇主要內(nèi)容

        這篇主要是理論 + 實踐相結(jié)合。實踐部分涉及到如何把鏈路追蹤組件 Sleuth + Zipkin 加到我的 Spring Cloud 《佳必過》開源項目上。

        本篇知識點:

        • 鏈路追蹤基本原理
        • 如何在項目中輕松加入鏈路追蹤中間件
        • 如何使用鏈路追蹤排查問題

        一、為什么要用鏈路追蹤?

        1.1 因:拆分服務(wù)單元

        微服務(wù)架構(gòu)其實是一個分布式的架構(gòu),按照業(yè)務(wù)劃分成了多個服務(wù)單元。

        由于服務(wù)單元的數(shù)量是很多的,有可能幾千個,而且業(yè)務(wù)也會更復(fù)雜,如果出現(xiàn)了錯誤和異常,很難去定位。

        1.2 因:邏輯復(fù)雜

        比如一個請求需要調(diào)用多個服務(wù)才能完成整個業(yè)務(wù)閉環(huán),而內(nèi)部服務(wù)的代碼邏輯和業(yè)務(wù)邏輯比較復(fù)雜,假如某個服務(wù)出現(xiàn)了問題,是難以快速確定那個服務(wù)出問題的。

        1.3 果:快速定位

        而如果我們加上了分布式鏈路追蹤,去跟蹤一個請求有哪些服務(wù)參與其中,參與的順序是怎樣的,這樣我們就知道了每個請求的詳細經(jīng)過,即使出了問題也能快速定位。

        二、鏈路追蹤的核心

        鏈路追蹤組件有 Twitter 的可視化鏈路追蹤組件 Zipkin、Google 的 Dapper、阿里的 Eagleeye 等,而 Sleuth 是 Spring Cloud 的組件。Spring Cloud Sleuth 借鑒了 Dapper 的術(shù)語。

        本文主要講解 Sleuth + Zipkin 結(jié)合使用來更好地實現(xiàn)鏈路追蹤。

        為什么能夠進行整條鏈路的追蹤?其實就是一個 Trace ID 將 一連串的 Span 信息連起來了。根據(jù) Span 記錄的信息再進行整合就可以獲取整條鏈路的信息。下面是鏈路追蹤的核心概念:

        2.1 Span(跨度)

        • 大白話:遠程調(diào)用和 Span ?一對一。

        • 基本的工作單元,每次發(fā)送一個遠程調(diào)用服務(wù)就會產(chǎn)生一個 Span。

        • Span 是一個 64 位的唯一 ID。

        • 通過計算 Span 的開始和結(jié)束時間,就可以統(tǒng)計每個服務(wù)調(diào)用所花費的時間。

        2.2 Trace(跟蹤)

        • 大白話:一個 Trace 對應(yīng)多個 Span,一對多。

        • 它由一系列 Span 組成,樹狀結(jié)構(gòu)。

        • 64 位唯一 ID。

        • 每次客戶端訪問微服務(wù)系統(tǒng)的 API 接口,可能中間會調(diào)用多個微服務(wù),每次調(diào)用都會產(chǎn)生一個新的 Span,而多個 Span 組成了 Trace

        2.3 Annotation(注解)

        鏈路追蹤系統(tǒng)定義了一些核心注解,用來定義一個請求的開始和結(jié)束,注意是微服務(wù)之間的請求,而不是瀏覽器或手機等設(shè)備。注解包括:

        • cs - Client Sent:客戶端發(fā)送一個請求,描述了這個請求調(diào)用的 Span 的開始時間。注意:這里的客戶端指的是微服務(wù)的調(diào)用者,不是我們理解的瀏覽器或手機等客戶端。
        • sr - Server Received:服務(wù)端獲得請求并準備開始處理它,如果將其 sr 減去 cs 時間戳,即可得到網(wǎng)絡(luò)傳輸時間。
        • ss - Server Sent:服務(wù)端發(fā)送響應(yīng),會記錄請求處理完成的時間,ss 時間戳減去 sr 時間戳,即可得到服務(wù)器請求的時間。
        • cr - Client Received:客戶端接收響應(yīng),Span 的結(jié)束時間,如果 cr 的時間戳減去 cs 時間戳,即可得到一次微服務(wù)調(diào)用所消耗的時間,也就是一個 Span 的消耗的總時間。

        2.4 鏈路追蹤原理

        假定三個微服務(wù)調(diào)用的鏈路如下圖所示:Service 1 調(diào)用 Service 2Service 2 調(diào)用 Service 3 和 Service 4。

        微服務(wù)調(diào)用鏈路圖

        那么鏈路追蹤會在每個服務(wù)調(diào)用的時候加上 Trace ID 和 Span ID。如下圖所示:

        鏈路追蹤原理圖

        大白話解釋:

        • 大家注意上面的顏色,相同顏色的代表是同一個 Span ID,說明是鏈路追蹤中的一個節(jié)點。

        • 第一步:客戶端調(diào)用 Service 1,生成一個 RequestTrace IDSpan ID 為空,那個時候請求還沒有到 Service 1

        • 第二步:請求到達 Service 1,記錄了 Trace ID = X,Span ID 等于 A。

        • 第三步:Service 1 發(fā)送請求給 Service 2,Span ID 等于 B,被稱作 Client Sent,即客戶端發(fā)送一個請求。

        • 第四步:請求到達 Service 2,Span ID 等于 B,Trace ID 不會改變,被稱作 Server Received,即服務(wù)端獲得請求并準備開始處理它。

        • 第五步:Service 2 開始處理這個請求,處理完之后,Trace ID 不變,Span ID = C。

        • 第六步:Service 2 開始發(fā)送這個請求給 Service 3,Trace ID 不變,Span ID = D,被稱作 Client Sent,即客戶端發(fā)送一個請求。

        • 第七步:Service 3 接收到這個請求,Span ID = D,被稱作 Server Received。

        • 第八步:Service 3 開始處理這個請求,處理完之后,Span ID = E。

        • 第九步:Service 3 開始發(fā)送響應(yīng)給 Service 2,Span ID = D,被稱作 Server Sent,即服務(wù)端發(fā)送響應(yīng)。

        • 第十步:Service 3 收到 Service 2 的響應(yīng),Span ID = D,被稱作 Client Received,即客戶端接收響應(yīng)。

        • 第十一步:Service 2 開始返回 響應(yīng)給 Service 1,Span ID = B,和第三步的 Span ID 相同,被稱作 Client Received,即客戶端接收響應(yīng)。

        • 第十二步:Service 1 處理完響應(yīng),Span ID = A,和第二步的 Span ID 相同。

        • 第十三步:Service 1 開始向客戶端返回響應(yīng),Span ID = A、

        • Service 3 向 Service 4 發(fā)送請求和 Service 3 類似,對應(yīng)的 Span ID 是 F 和 G??梢詤⒄丈厦媲懊娴牡诹降降谑?。

        把以上的相同顏色的步驟簡化為下面的鏈路追蹤圖:

        鏈路追蹤父子節(jié)點圖
        • 第一個節(jié)點:Span ID = A,Parent ID = null,Service 1 接收到請求。
        • 第二個節(jié)點:Span ID = B,Parent ID= A,Service 1 發(fā)送請求到 Service 2 返回響應(yīng)給 Service 1 的過程。
        • 第三個節(jié)點:Span ID = C,Parent ID= B,Service 2 的 中間處理過程。
        • 第四個節(jié)點:Span ID = D,Parent ID= C,Service 2 發(fā)送請求到 Service 3 返回響應(yīng)給 Service 2 的過程。
        • 第五個節(jié)點:Span ID = E,Parent ID= D,Service 3 的中間處理過程。
        • 第六個節(jié)點:Span ID = F,Parent ID= C,Service 3 發(fā)送請求到 Service 4 返回響應(yīng)給 Service 3 的過程。
        • 第七個節(jié)點:Span ID = G,Parent ID= F,Service 4 的中間處理過程。

        通過 Parent ID 即可找到父節(jié)點,整個鏈路就可以進行跟蹤追溯了。

        三、Spring Cloud 整合 Sleuth

        大家可以參照我的 GitHub 開源項目 PassJava(佳必過)。

        3.1 引入 Spring Cloud 依賴

        在 passjava-common 中引入 Spring Cloud 依賴

        因為我們使用的鏈路追蹤組件 Sleuth 是 Spring Cloud 的組件,所以我們需要引入 Spring Cloud 依賴。


        ????
        ????????
        ????????
        ????????????org.springframework.cloud
        ????????????spring-cloud-dependencies
        ????????????Hoxton.SR3
        ????????????<type>pomtype>
        ????????????import
        ????????

        ????


        3.2 引入Sleuth依賴

        引入鏈路追蹤組件 Sleuth 非常簡單,在 pom.xml 文件中引入 Sleuth 依賴即可。

        在 passjava-common 中引入 Sleuth 依賴:


        <dependency>
        ?<groupId>org.springframework.cloudgroupId>
        ????<artifactId>spring-cloud-starter-sleuthartifactId>
        dependency>

        3.3 通過日志觀察鏈路追蹤

        我們先不整合 zipkin 鏈路追蹤可視化組件,而是通過日志的方式來查看鏈路追蹤信息。

        文件路徑:\PassJava-Platform\passjava-question\src\main\resources\application.properties
        添加配置:
        logging.level.org.springframework.cloud.openfeign=debug
        logging.level.org.springframework.cloud.sleuth=debug

        3.4 啟動微服務(wù)

        啟動以下微服務(wù):

        • passjava-gateway 服務(wù)(網(wǎng)關(guān))

        • passjava-question 服務(wù)(題目中心微服務(wù))

        • renren 服務(wù)(Admin 后臺管理服務(wù))

          啟動成功后如下圖所示:

        啟動微服務(wù)

        3.5 測試跟蹤請求

        打開 Admin 后臺,訪問題目中心->題目配置頁面,可以看到發(fā)送了下面的請求:

        http://localhost:8060/api/question/v1/admin/question/list?t=1605170539929&page=1&limit=10&key=
        佳必過項目的后臺界面

        打開控制臺,可以看到打印出了追蹤日志。

        鏈路追蹤日志

        說明:

        • 當沒有配置 Sleuth 鏈路追蹤的時候,INFO 信息里面是 [passjava-question,,,],后面跟著三個空字符串。
        • 當配置了 Sleuth 鏈路追蹤的時候,追蹤到的信息是 [passjava-question,504a5360ca906016,e55ff064b3941956,false] ,第一個是 Trace ID,第二個是 Span ID。

        四、Zipkin 鏈路追蹤原理

        上面我們通過簡單的引入 Sleuth 組件,就可以獲取到調(diào)用鏈路,但只能通過控制臺的輸出信息來看,不太方便。

        Zipkin 油然而生,一個圖形化的工具。Zipkin 是 Twitter 開源的分布式跟蹤系統(tǒng),主要用來用來收集系統(tǒng)的時序數(shù)據(jù),進而可以跟蹤系統(tǒng)的調(diào)用問題。

        而且引入了 Zipkin 組件后,就不需要引入 Sleuth 組件了,因為 Zipkin 組件已經(jīng)幫我們引入了。

        Zipkin 的官網(wǎng):https://zipkin.io

        4.1 Zipkin 基礎(chǔ)架構(gòu)

        Zipkin 基礎(chǔ)架構(gòu)

        Zipkin 包含四大組件:

        • Collection(收集器組件),主要負責收集外部系統(tǒng)跟蹤信息。
        • Storage(存儲組件),主要負責將收集到的跟蹤信息進行存儲,默認存放在內(nèi)存中,支持存儲到 MySQL 和 ElasticSearch。
        • API(查詢組件),提供接口查詢跟蹤信息,給 UI 組件用的。
        • UI (可視化 Web UI 組件),可以基于服務(wù)、時間、注解來可視化查看跟蹤信息。注意:Web UI 不需要身份驗證。

        4.2 Zipkin 跟蹤流程

        Zipkin 跟蹤流程

        流程解釋:

        • 第一步:用戶代碼發(fā)起 HTTP Get 請求,請求路徑:/foo。
        • 第二步:請求到到跟蹤工具后,請求被攔截,會被記錄兩項信息:標簽和時間戳。以及HTTP Headers 里面會增加跟蹤頭信息。
        • 第三步:將封裝好的請求傳給 HTTP 客戶端,請求中包含 X-B3-TraceID 和 X-B3-SpanId 請求頭信息。
        • 第四步:由HTTP 客戶端發(fā)送請求。
        • 第五步:Http 客戶端返回響應(yīng) 200 OK 后,跟蹤工具記錄耗時時間。
        • 第六步:跟蹤工具發(fā)送 200 OK 給用戶端。
        • 第七步:異步報告 Span 信息給 Zipkin 收集器。

        五、整合 Zipkin 可視化組件

        5.1 啟動虛擬機并連接

        vagrant?up
        啟動虛擬機

        接著就可以用 Xshell 工具連接虛擬機了。下面是在命令行里面執(zhí)行相關(guān)操作。

        5.2 docker 安裝 zipkin 服務(wù)

        • 使用以下命令開始拉取 zipkin 鏡像并啟動 zipkin 容器。
        docker?run?-d?-p?9411:9411?openzipkin/zipkin
        • 命令執(zhí)行完后,會執(zhí)行下載操作和啟動操作。
        docker 安裝 zipkin 服務(wù)
        • 使用 docker ps 命令可以看到 zipkin 容器已經(jīng)啟動成功了。如下圖所示:
        zipkin 容器啟動成功
        • 在瀏覽器窗口打開 zipkin UI

        訪問服務(wù)地址:http://192.168.56.10:9411/zipkin。

        5.3 引入 Zipkin 依賴

        在公共模塊引入 zipkin 依賴


        <dependency>
        ????<groupId>org.springframework.cloudgroupId>
        ????<artifactId>spring-cloud-starter-zipkinartifactId>
        dependency>

        因為 zipkin 包里面已經(jīng)引入了 sleuth 組件,所以可以把之前引入的 sleuth 組件刪掉。

        5.4 添加 Zipkin 配置

        在需要追蹤的微服務(wù)模塊下添加 zipkin 配置。

        # zipkin 的服務(wù)器地址
        spring.zipkin.base-url=http://192.168.56.10:9411/
        # 關(guān)閉服務(wù)發(fā)現(xiàn),否則 Spring Cloud 會把 zipkin 的 URL 當作服務(wù)名稱。
        spring.zipkin.discovery-client-enabled=false
        # 設(shè)置使用 http 的方式傳輸數(shù)據(jù),也可以用 RabbitMQ 或 Kafka。
        spring.zipkin.sender.type=web
        # 設(shè)置采樣率為 100 %,默認為 0.1(10%)
        spring.sleuth.sampler.probability=1

        5.5 測試 Zipkin 是否工作

        這里我在 passjava-member 微服務(wù)中寫了一個 API:

        passjava-member 服務(wù)的 API:getMemberStudyTimeListTest,

        訪問路徑為/studytime/list/test/{id}。

        passjava-member 服務(wù)遠程調(diào)用 passjava-study 服務(wù)。

        對應(yīng)的 API:getMemberStudyTimeListTest。

        我用 postman 工具測試 passjava-member 服務(wù)的 API:

        測試 Passjava-member 服務(wù)的 API

        打開 Zipkin 工具,搜索 passjava-member 的鏈路追蹤日志,可以看到有一條記錄,相關(guān)說明如下圖所示:

        zipkin 示例

        從圖中可以看到 passjava-member 微服務(wù)調(diào)用了 passjava-study 微服務(wù),如圖中左半部分所示。

        而且 passjava-study 微服務(wù)詳細的調(diào)用時間都記錄得非常清楚,如圖中右半部分所示。

        時間計算:

        • 請求傳輸時間:Server Start - Client Start = 2.577s-2.339s = 0.238s
        • 服務(wù)端處理時間:Server Finish - Server Start = 2.863s - 2.577s = 0.286s
        • 請求總耗時:Client Finish - Client Start = 2.861s - 2.339s = 0.522s
        • Passjava-member 服務(wù)總耗時:3.156 s
        • Passjava-study 服務(wù)總耗時:0.521s
        • 由此可以看出 passjava-member 服務(wù)花費了很長時間,性能很差。

        另外還可以用圖表的方式查看跟蹤信息,這里不做展開了。

        圖表的方式查看

        六、Zipkin 數(shù)據(jù)持久化

        6.1 Zipkin 支持的數(shù)據(jù)庫

        Zipkin 存儲數(shù)據(jù)默認是放在內(nèi)存中的,如果 Zipkin 重啟,那么監(jiān)控數(shù)據(jù)也會丟失。如果是生成環(huán)境,數(shù)據(jù)丟失會帶來很大問題,所以需要將 Zipkin 的監(jiān)控數(shù)據(jù)持久化。而 Zipkin 支持將數(shù)據(jù)存儲到以下數(shù)據(jù)庫:

        • 內(nèi)存(默認,不建議使用)
        • MySQL(數(shù)據(jù)量大的話, 查詢較為緩慢,不建議使用)
        • Elasticsearch(建議使用)
        • Cassandra(國內(nèi)使用 Cassandra 的公司較少,相關(guān)文檔也不多)

        6.2 使用 Elasticsearch 作為儲存介質(zhì)

        • 通過 docker 的方式配置 elasticsearch 作為 zipkin 數(shù)據(jù)的存儲介質(zhì)。
        docker?run?--env?STORAGE_TYPE=elasticsearch?--env?ES_HOSTS=192.168.56.10:9200?openzipkin/zipkin-dependencies
        • ES 作為存儲介質(zhì)的配置參數(shù):
        ES 作為存儲介質(zhì)的配置參數(shù)

        七、總結(jié)

        本篇講解了鏈路追蹤的核心原理,以及 Sleuth + Zipkin 的組件的原理,以及將這兩款組件加到了我的開源項目《佳必過》里面了。

        開源項目地址:https://github.com/Jackson0714/PassJava-Platform


        ? ? ? ?
        ???
        刨根問底,Kafka 消息中間件到底會不會丟消息
        炸了!一口氣問了我18個JVM問題!
        深度揭秘垃圾回收底層,這次讓你徹底弄懂她

        覺得不錯,點個在看~

        瀏覽 40
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            68精品国产免费久久久久久婷婷 | 日本级婬乱片A片AAA毛片A | 4p调教三根一起男男爽妇网 | 美女麻批日出白浆 | 欧美精品性爱视频 | 亚洲精品极品 | 亚洲黄在线 | juy一268被爱弄湿的午后 | 浴室里强摁做开腿呻吟的 | 福瑞控18禁无遮挡▓网站入口 |