1. 程式人生 > >微服務架構下,如何實現分散式跟蹤?

微服務架構下,如何實現分散式跟蹤?

前段時間,我們有釋出過一篇題為《類似Google Dapper,微服務需要這樣的分散式跟蹤工具》的文章,很多讀者反饋沒看盡興,確實,文章只是談到分散式追蹤工具的意義,以及可以解決什麼問題,但並沒有談到如何實現分散式追蹤。今天這篇文章,作者是東軟集團基礎軟體事業部技術總監,他在這方面有豐富的經驗,文中他將會聊到目前主流的幾個解決方案實現思路以及他們的落地方案。

另外,這裡有個不錯的關於Spring Boot和Spring Cloud的沙龍活動,免費,在北京,感興趣的同學別忘了報名

隨著網際網路技術的高速發展,各種創新技術、前沿概念如雨後春筍般層出不窮,雲服務、雲端計算、大資料處理、大資料分析……,以往單應用的服務架構已經很難處理如山洪般增長的資訊資料,隨著分散式的普及、服務的快速增長與雲端計算技術的進步,微服務架構逐漸進入人們的實現,它也因其特有的優勢而備受關注。

微服務架構的本質,是把整體的業務拆分成很多有特定明確功能的服務,通過很多分散的小服務之間的配合,去解決更大,更復雜的問題。對被拆分後的服務進行分類和管理,彼此之間使用統一的介面來進行互動。

微服務的特點決定了功能模組的部署是分散式的,以往在單應用環境下,所有的業務都在同一個伺服器上,如果伺服器出現錯誤和異常,我們只要盯住一個點,就可以快速定位和處理問題,但是在微服務的架構下,大部分功能模組都是單獨部署執行的,彼此通過匯流排互動,都是無狀態的服務,這種架構下,前後臺的業務流會經過很多個微服務的處理和傳遞,我們難免會遇到這樣的問題:

  • 分散在各個伺服器上的日誌怎麼處理?
  • 如果業務流出現了錯誤和異常,如何定位是哪個點出的問題?
  • 如何快速定位問題?
  • 如何跟蹤業務流的處理順序和結果?

我們發現,以前在單應用下的日誌監控很簡單,在微服務架構下卻成為了一個大問題,如果無法跟蹤業務流,無法定位問題,我們將耗費大量的時間來查詢和定位問題,在複雜的微服務互動關係中,我們就會非常被動。

對於這個問題,業內已經有了一些實踐和解決方案,讓我們來看看行業內的領先設計思想。

Google Dapper

Google公司廣泛使用了分散式叢集,為了應對自身大規模的複雜叢集環境,Google公司研發了Dapper分散式跟蹤系統,並發表了論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,給行業內分散式跟蹤的實現提供了非常有價值的參考,該論文也成為了當前分散式跟蹤系統的理論基礎。

我們先來看個例子:

圖1 這個路徑由使用者的X請求發起,穿過一個簡單的服務系統。用字母標識的節點代表分散式系統中的不同處理過程。

分散式服務的跟蹤系統需要記錄在一次特定的請求中系統中完成的所有工作的資訊。舉個例子,上圖展現的是一個與5臺伺服器相關的一個服務,包括:前端(A),兩個中間層(B和C),以及兩個後端(D和E)。當一個使用者(這個用例的發起人)發起一個請求時,首先到達前端,然後傳送兩個RPC呼叫到伺服器B和C。B會馬上做出反應,但是C需要和後端的D和E互動之後再返還給A,由A來響應最初的請求。對於這樣一個請求,簡單實用的分散式跟蹤的實現,就是為伺服器上每一次傳送和接收動作來收集跟蹤識別符號(message identifiers)和時間戳(timestamped events)。

基於這個模型,Google在此論文中提出了幾個重要的概念:

1、基於標註(annotation-based),又叫植入點或埋點

在應用程式或中介軟體中明確定義一個全域性的標註(annotation),它可以是一個特殊的ID,通過這個ID連線每一條記錄和發起者的請求,當然,這需要程式碼植入,在生產環境中,因為所有的應用程式都使用相同的執行緒模型,控制流和RPC系統,可以把程式碼植入限制在一個很小的通用元件庫中,從而達到監測系統應用對開發人員的透明。Dapper能夠以對應用開發者近乎零侵入的成本對分散式控制路徑進行跟蹤,幾乎完全依賴於少量通用元件庫的改造。

  • 當一個執行緒在處理跟蹤控制路徑的過程中,Dapper把這次跟蹤的上下文在ThreadLocal中進行儲存。追蹤上下文是一個小而且容易複製的容器,其中承載了Scan的屬性比如跟蹤ID和span ID。

  • 當計算過程是延遲呼叫的或是非同步的,大多數Google開發者通過執行緒池或其他執行器,使用一個通用的控制流庫來回調。Dapper確保所有這樣的回撥可以儲存這次跟蹤的上下文,而當回撥函式被觸發時,這次跟蹤的上下文會與適當的執行緒關聯。在這種方式下,Dapper可以使用trace ID和span ID來輔助構建非同步呼叫的路徑。

  • Google幾乎所有的程序間通訊都是建立在一個用C++和Java開發的RPC框架上。我們通過跟蹤植入該框架來定義RPC中所有的span。span的ID和跟蹤的ID會從客戶端傳送到服務端。基於RPC的系統被廣泛使用在Google中,這是一個重要的植入點。

2、跟蹤樹和span

圖2:5個span在Dapper跟蹤樹中的關聯關係

在Dapper跟蹤樹結構中,樹節點是整個架構的基本單元,而每一個節點又是對span的引用。節點之間的連線表示的span和它的父span的直接關係。通過簡單的parentId和spanId就可以有序地把所有的關係串聯起來,達到記錄業務流的作用。

Twitter公司的Zipkin

Twitter公司的Zipkin是Google Dapper系統的開源實現,Zipkin嚴格按照Dapper論文實現,採用Scala編寫,並且緊密整合到Twitter公司自己的分散式服務Finagle中,使得跟蹤做到對應用透明。

圖3:Zipkin應用架構圖

Zipkin的整體架構如上圖所示,涵蓋了資訊的收集、處理和展現。

淘寶鷹眼系統(EagleEye)

淘寶鷹眼是基於網路呼叫日誌的分散式跟蹤系統,它可以分析網路請求在各個分散式系統之間的呼叫情況,從而得到處理請求的呼叫鏈上的入口URL、應用服務的呼叫關係,從而找到請求處理瓶頸,定位錯誤異常的根源位置。同時,業務方也可以在呼叫鏈上新增自己的業務埋點日誌,使各個系統的網路呼叫與實際業務內容得到關聯。

圖4:鷹眼系統的總體架構圖

我們的解決方案

針對於微服務,東軟平臺產品提供了一套完整的微服務解決方案,在此基礎上,對微服務架構進行了擴充套件,基於Google Dapper的概念,設計了一套基於微服務架構的分散式跟蹤系統。

該跟蹤系統支援基於dubbo的微服務框架的監控,以及分散式服務呼叫鏈跟蹤:

圖5:東軟UniEAP平臺基於微服務的分散式跟蹤系統流程設計圖

分散式跟蹤系統的整體流程是通過擴充套件dubbo作為入口,把監控程式碼植入到dubbo-filter擴充套件模組中,然後通過trace-client模組抓取日誌資料,存入檔案伺服器,為了避免產生大量Trace物件造成記憶體堆積引發的GC問題,trace首先採取寫入堆外記憶體的方式落地,然後通過trace-agent代理模組讀取日誌資訊,給trace-collector收集模組提供日誌資料,trace-collector收集模組通過提供統一的介面,為外部獲取資料提供支援,可以傳輸到資料庫記錄,或者傳輸給其他的資料分析產品。Trace-web模組作為視覺化展示平臺,展現服務的完整跟蹤鏈條、心跳監控資訊、dubbo原生監控資訊,達到資料的展示工作。

除了資料的跟蹤以外,該系統還會整合資料分析功能:

圖6:整合資料分析功能,提升資料的利用價值

通過整合視覺化分析產品,簡單的分散式跟蹤功能變成了視覺化的監控系統,跟蹤中產生的資料,會發揮出更大的價值:

  1. 實時抓取資料,實時分析統計,生成統計和報表

  2. 視覺化的報表系統,更快的瞭解系統執行狀態

  3. 搜尋功能,快速的定位關鍵問題

  4. 資料挖據,利用優秀的資料分析能力和資料模型,進行資料預測

  5. 分散式跟蹤系統應用展望

在分散式場景越來越普及的今天,分散式跟蹤將作為微服務必備的基礎元件存在,完善的跟蹤系統可以極大的提高開發和運維的效率,是企業應用發展不可獲缺的組成部分,特別是以下幾點:

1、業務流呼叫流程跟蹤

分散式系統的所有日誌資訊可以通過完善的跟蹤串聯起來,使系統的運維更加穩定,定位問題更加準確。

2、視覺化的監控介面

通過分散式跟蹤系統的視覺化監控頁面,避免了去伺服器上檢視日誌的煩惱。

3、業務分析

在使用了分散式跟蹤系統後,我們可以快速的梳理每個呼叫鏈路,分析耗時過長的業務是如何產生的,並且可以定位效能不佳的呼叫片段,合理的分析問題,為效能優化提供非常有價值的參考意見。