從0開始學微服務:08 如何追蹤微服務調用?

從0開始學微服務:08 如何追蹤微服務調用?

在微服務架構下,由於進行了服務拆分,一次請求往往需要涉及多個服務,每個服務可能是由不同的團隊開發,使用了不同的編程語言,還有可能部署在不同的機器上,分佈在不同的數據中心。

下面這張圖描述了用戶訪問微博首頁,一次請求所涉及的服務(這張圖僅作為示意,實際上可能遠遠比這張圖還要複雜),你可以想象如果這次請求失敗了,要想查清楚到底是哪個應用導致,會是多麼複雜的一件事情。

從0開始學微服務:08 如何追蹤微服務調用?

如果有一個系統,可以跟蹤記錄一次用戶請求都發起了哪些調用,經過哪些服務處理,並且記錄每一次調用所涉及的服務的詳細信息,這時候如果發生調用失敗,你就可以通過這個日誌快速定位是在哪個環節出了問題,這個系統就是今天我要講解的服務追蹤系統。

服務追蹤的作用

在介紹追蹤原理與實現之前,我們先來看看服務追蹤的作用。除了剛才說的能夠快速定位請求失敗的原因以外,我這裡再列出四點,它們可以幫你在微服務改造過程中解決不少問題。

第一,優化系統瓶頸。

通過記錄調用經過的每一條鏈路上的耗時,我們能快速定位整個系統的瓶頸點在哪裡。比如你訪問微博首頁發現很慢,肯定是由於某種原因造成的,有可能是運營商網絡延遲,有可能是網關係統異常,有可能是某個服務異常,還有可能是緩存或者數據庫異常。通過服務追蹤,可以從全局視角上去觀察,找出整個系統的瓶頸點所在,然後做出針對性的優化。

第二,優化鏈路調用。

通過服務追蹤可以分析調用所經過的路徑,然後評估是否合理。比如一個服務調用下游依賴了多個服務,通過調用鏈分析,可以評估是否每個依賴都是必要的,是否可以通過業務優化來減少服務依賴。

還有就是,一般業務都會在多個數據中心都部署服務,以實現異地容災,這個時候經常會出現一種狀況就是服務 A 調用了另外一個數據中心的服務 B,而沒有調用同處於一個數據中心的服務 B。

根據我的經驗,跨數據中心的調用視距離遠近都會有一定的網絡延遲,像北京和廣州這種幾千公里距離的網絡延遲可能達到 30ms 以上,這對於有些業務幾乎是不可接受的。通過對調用鏈路進行分析,可以找出跨數據中心的服務調用,從而進行優化,儘量規避這種情況出現。

第三,生成網絡拓撲。

通過服務追蹤系統中記錄的鏈路信息,可以生成一張系統的網絡調用拓撲圖,它可以反映系統都依賴了哪些服務,以及服務之間的調用關係是什麼樣的,可以一目瞭然。除此之外,在網絡拓撲圖上還可以把服務調用的詳細信息也標出來,也能起到服務監控的作用。

第四,透明傳輸數據。

除了服務追蹤,業務上經常有一種需求,期望能把一些用戶數據,從調用的開始一直往下傳遞,以便系統中的各個服務都能獲取到這個信息。比如業務想做一些 A/B 測試,這時候就想通過服務追蹤系統,把 A/B 測試的開關邏輯一直往下傳遞,經過的每一層服務都能獲取到這個開關值,就能夠統一進行 A/B 測試。

服務追蹤系統原理

講到這裡,你一定很好奇,服務追蹤有這麼多好處,那它是怎麼做到的呢?

這就不得不提到服務追蹤系統的鼻祖:Google 發佈的一篇的論文Dapper, a Large-Scale Distributed Systems Tracing Infrastructure,裡面詳細講解了服務追蹤系統的實現原理。它的核心理念就是調用鏈:通過一個全局唯一的 ID 將分佈在各個服務節點上的同一次請求串聯起來,從而還原原有的調用關係,可以追蹤系統問題、分析調用數據並統計各種系統指標。

可以說後面的誕生各種服務追蹤系統都是基於 Dapper 衍生出來的,比較有名的有 Twitter 的Zipkin、阿里的鷹眼、美團的MTrace等。

要理解服務追蹤的原理,首先必須搞懂一些基本概念:traceId、spanId、annonation 等。Dapper 這篇論文講得比較清楚,但對初學者來說理解起來可能有點困難,美團的 MTrace 的原理介紹理解起來相對容易一些,下面我就以 MTrace 為例,給你詳細講述服務追蹤系統的實現原理。雖然原理有些晦澀,但卻是你必須掌握的,只有理解了服務追蹤的基本概念,才能更好地將其實現出來。

首先看下面這張圖,我來給你講解下服務追蹤系統中幾個最基本概念。

從0開始學微服務:08 如何追蹤微服務調用?

  • traceId,用於標識某一次具體的請求 ID。當用戶的請求進入系統後,會在 RPC 調用網絡的第一層生成一個全局唯一的 traceId,並且會隨著每一層的 RPC 調用,不斷往後傳遞,這樣的話通過 traceId 就可以把一次用戶請求在系統中調用的路徑串聯起來。
  • spanId,用於標識一次 RPC 調用在分佈式請求中的位置。當用戶的請求進入系統後,處在 RPC 調用網絡的第一層 A 時 spanId 初始值是 0,進入下一層 RPC 調用 B 的時候 spanId 是 0.1,繼續進入下一層 RPC 調用 C 時 spanId 是 0.1.1,而與 B 處在同一層的 RPC 調用 E 的 spanId 是 0.2,這樣的話通過 spanId 就可以定位某一次 RPC 請求在系統調用中所處的位置,以及它的上下游依賴分別是誰。
  • annotation,用於業務自定義埋點數據,可以是業務感興趣的想上傳到後端的數據,比如一次請求的用戶 UID。

上面這三段內容我用通俗語言再給你小結一下,traceId 是用於串聯某一次請求在系統中經過的所有路徑,spanId 是用於區分系統不同服務之間調用的先後關係,而 annotation 是用於業務自定義一些自己感興趣的數據,在上傳 traceId 和 spanId 這些基本信息之外,添加一些自己感興趣的信息。

服務追蹤系統實現

講到這裡,你應該已經理解服務追蹤系統裡最重要的概念和原理了,我們先來看看服務追蹤系統的架構,讓你瞭解一下系統全貌。

從0開始學微服務:08 如何追蹤微服務調用?

上面是服務追蹤系統架構圖,你可以看到一個服務追蹤系統可以分為三層。

  • 數據採集層,負責數據埋點並上報。
  • 數據處理層,負責數據的存儲與計算。
  • 數據展示層,負責數據的圖形化展示。

下面來看看具體每一層的實現方式是什麼樣的。

1. 數據採集層

數據採集層的作用就是在系統的各個不同模塊中進行埋點,採集數據並上報給數據處理層進行處理。

那麼該如何進行數據埋點呢?結合下面這張圖來了解一下數據埋點的流程。

從0開始學微服務:08 如何追蹤微服務調用?

以紅色方框裡圈出的 A 調用 B 的過程為例,一次 RPC 請求可以分為四個階段。

  • CS(Client Send)階段 : 客戶端發起請求,並生成調用的上下文。
  • SR(Server Recieve)階段 : 服務端接收請求,並生成上下文。
  • SS(Server Send)階段 : 服務端返回請求,這個階段會將服務端上下文數據上報,下面這張圖可以說明上報的數據有:traceId=123456,spanId=0.1,appKey=B,method=B.method,start=103,duration=38。
  • CR(Client Recieve)階段 : 客戶端接收返回結果,這個階段會將客戶端上下文數據上報,上報的數據有:traceid=123456,spanId=0.1,appKey=A,method=B.method,start=103,duration=38。
從0開始學微服務:08 如何追蹤微服務調用?

2. 數據處理層

數據處理層的作用就是把數據採集層上報的數據按需計算,然後落地存儲供查詢使用。

據我所知,數據處理的需求一般分為兩類,一類是實時計算需求,一類是離線計算需求。

實時計算需求對計算效率要求比較高,一般要求對收集的鏈路數據能夠在秒級別完成聚合計算,以供實時查詢。而離線計算需求對計算效率要求就沒那麼高了,一般能在小時級別完成鏈路數據的聚合計算即可,一般用作數據彙總統計。針對這兩類不同的數據處理需求,採用的計算方法和存儲也不相同。

實時數據處理

針對實時數據處理,一般採用 Storm 或者 Spark Streaming 來對鏈路數據進行實時聚合加工,存儲一般使用 OLTP 數據倉庫,比如 HBase,使用 traceId 作為 RowKey,能天然地把一整條調用鏈聚合在一起,提高查詢效率。

離線數據處理

針對離線數據處理,一般通過運行 MapReduce 或者 Spark 批處理程序來對鏈路數據進行離線計算,存儲一般使用 Hive。

3. 數據展示層

數據展示層的作用就是將處理後的鏈路信息以圖形化的方式展示給用戶。

根據我的經驗,實際項目中主要用到兩種圖形展示,一種是調用鏈路圖,一種是調用拓撲圖。

調用鏈路圖

下面以一張 Zipkin 的調用鏈路圖為例,通過這張圖可以看出下面幾個信息。

服務整體情況:服務總耗時、服務調用的網絡深度、每一層經過的系統,以及多少次調用。下圖展示的一次調用,總共耗時 209.323ms,經過了 5 個不同的系統模塊,調用深度為 7 層,共發生了 24 次系統調用。

每一層的情況:每一層發生了幾次調用,以及每一層調用的耗時。

從0開始學微服務:08 如何追蹤微服務調用?

根據我的經驗,調用鏈路圖在實際項目中,主要是被用來做故障定位,比如某一次用戶調用失敗了,可以通過調用鏈路圖查詢這次用戶調用經過了哪些環節,到底是哪一層的調用失敗所導致。

調用拓撲圖

下面是一張 Pinpoint 的調用拓撲圖,通過這張圖可以看出系統內都包含哪些應用,它們之間是什麼關係,以及依賴調用的 QPS、平均耗時情況。

從0開始學微服務:08 如何追蹤微服務調用?

調用拓撲圖是一種全局視野圖,在實際項目中,主要用作全局監控,用於發現系統中異常的點,從而快速做出決策。比如,某一個服務突然出現異常,那麼在調用鏈路拓撲圖中可以看出對這個服務的調用耗時都變高了,可以用紅色的圖樣標出來,用作監控報警。

總結

今天我給你講解了服務追蹤的基本原理以及實現方式,可以說服務追蹤是分佈式系統中必不可少的功能,它能夠幫助我們查詢一次用戶請求在系統中的具體執行路徑,以及每一條路徑的上下游的詳細情況,對於追查問題十分有用。

實現一個服務追蹤系統,涉及數據採集、數據處理和數據展示這三個流程,有多種實現方式,具體採用哪一種要根據自己的業務情況來選擇。關於服務追蹤系統的選型我在專欄後面會詳細展開介紹,這裡你只需要瞭解它的基本工作原理就可以了。

思考題

通過這兩期的學習,你應該瞭解到服務追蹤系統和服務監控系統的搭建都需要數據採集、處理和展示這三個步驟,你認為它們是否有相同和不同之處呢?


分享到:


相關文章: