隨著互聯(lián)網(wǎng)技術(shù)的高速發(fā)展,各種創(chuàng)新技術(shù)、前沿概念如雨后春筍般層出不窮,云服務、云計算、大數(shù)據(jù)處理、大數(shù)據(jù)分析……,以往單應用的服務架構(gòu)已經(jīng) 很難處理如山洪般增長的信息數(shù)據(jù),隨著分布式的普及、服務的快速增長與云計算技術(shù)的進步,微服務架構(gòu)逐漸進入人們的實現(xiàn),它也因其特有的優(yōu)勢而備受關(guān)注。
微服務架構(gòu)的本質(zhì),是把整體的業(yè)務拆分成很多有特定明確功能的服務,通過很多分散的小服務之間的配合,去解決更大,更復雜的問題。對被拆分后的服務進行分類和管理,彼此之間使用統(tǒng)一的接口來進行交互。
微服務的特點決定了功能模塊的部署是分布式的,以往在單應用環(huán)境下,所有的業(yè)務都在同一個服務器上,如果服務器出現(xiàn)錯誤和異常,我們只要盯住一個 點,就可以快速定位和處理問題,但是在微服務的架構(gòu)下,大部分功能模塊都是單獨部署運行的,彼此通過總線交互,都是無狀態(tài)的服務,這種架構(gòu)下,前后臺的業(yè) 務流會經(jīng)過很多個微服務的處理和傳遞,我們難免會遇到這樣的問題:
分散在各個服務器上的日志怎么處理?
如果業(yè)務流出現(xiàn)了錯誤和異常,如何定位是哪個點出的問題?
如何快速定位問題?
如何跟蹤業(yè)務流的處理順序和結(jié)果?
我們發(fā)現(xiàn),以前在單應用下的日志監(jiān)控很簡單,在微服務架構(gòu)下卻成為了一個大問題,如果無法跟蹤業(yè)務流,無法定位問題,我們將耗費大量的時間來查找和定位問題,在復雜的微服務交互關(guān)系中,我們就會非常被動。
對于這個問題,業(yè)內(nèi)已經(jīng)有了一些實踐和解決方案,讓我們來看看行業(yè)內(nèi)的領(lǐng)先設計思想。
Google Dapper
Google公司廣泛使用了分布式集群,為了應對自身大規(guī)模的復雜集群環(huán)境,Google公司研發(fā)了Dapper分布式跟蹤系統(tǒng),并發(fā)表了論文 《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,給行業(yè)內(nèi)分布式跟蹤的實現(xiàn)提供了非常有價值的參考,該論文也成為了當前分布式跟蹤系統(tǒng)的理論基礎(chǔ)。
我們先來看個例子:
圖1 這個路徑由用戶的X請求發(fā)起,穿過一個簡單的服務系統(tǒng)。用字母標識的節(jié)點代表分布式系統(tǒng)中的不同處理過程。
分布式服務的跟蹤系統(tǒng)需要記錄在一次特定的請求中系統(tǒng)中完成的所有工作的信息。舉個例子,上圖展現(xiàn)的是一個與5臺服務器相關(guān)的一個服務,包括:前端 (A),兩個中間層(B和C),以及兩個后端(D和E)。當一個用戶(這個用例的發(fā)起人)發(fā)起一個請求時,首先到達前端,然后發(fā)送兩個RPC調(diào)用到服務器 B和C。B會馬上做出反應,但是C需要和后端的D和E交互之后再返還給A,由A來響應最初的請求。對于這樣一個請求,簡單實用的分布式跟蹤的實現(xiàn),就是為 服務器上每一次發(fā)送和接收動作來收集跟蹤標識符(message identifiers)和時間戳(timestamped events)。
基于這個模型,Google在此論文中提出了幾個重要的概念:
1、基于標注(annotation-based),又叫植入點或埋點
在應用程序或中間件中明確定義一個全局的標注(annotation),它可以是一個特殊的ID,通過這個ID連接每一條記錄和發(fā)起者的請求,當 然,這需要代碼植入,在生產(chǎn)環(huán)境中,因為所有的應用程序都使用相同的線程模型,控制流和RPC系統(tǒng),可以把代碼植入限制在一個很小的通用組件庫中,從而達 到監(jiān)測系統(tǒng)應用對開發(fā)人員的透明。Dapper能夠以對應用開發(fā)者近乎零侵入的成本對分布式控制路徑進行跟蹤,幾乎完全依賴于少量通用組件庫的改造。
當一個線程在處理跟蹤控制路徑的過程中,Dapper把這次跟蹤的上下文在ThreadLocal中進行存儲。追蹤上下文是一個小而且容易復制的容器,其中承載了Scan的屬性比如跟蹤ID和span ID。
當計算過程是延遲調(diào)用的或是異步的,大多數(shù)Google開發(fā)者通過線程池或其他執(zhí)行器,使用一個通用的控制流庫來回調(diào)。Dapper確保所有這樣 的回調(diào)可以存儲這次跟蹤的上下文,而當回調(diào)函數(shù)被觸發(fā)時,這次跟蹤的上下文會與適當?shù)木€程關(guān)聯(lián)。在這種方式下,Dapper可以使用trace ID和span ID來輔助構(gòu)建異步調(diào)用的路徑。
Google幾乎所有的進程間通信都是建立在一個用C++和Java開發(fā)的RPC框架上。我們通過跟蹤植入該框架來定義RPC中所有的span。span的ID和跟蹤的ID會從客戶端發(fā)送到服務端?;赗PC的系統(tǒng)被廣泛使用在Google中,這是一個重要的植入點。
2、跟蹤樹和span
圖2:5個span在Dapper跟蹤樹中的關(guān)聯(lián)關(guān)系
在Dapper跟蹤樹結(jié)構(gòu)中,樹節(jié)點是整個架構(gòu)的基本單元,而每一個節(jié)點又是對span的引用。節(jié)點之間的連線表示的span和它的父span的直接關(guān)系。通過簡單的parentId和spanId就可以有序地把所有的關(guān)系串聯(lián)起來,達到記錄業(yè)務流的作用。
Twitter公司的Zipkin
Twitter公司的Zipkin是Google Dapper系統(tǒng)的開源實現(xiàn),Zipkin嚴格按照Dapper論文實現(xiàn),采用Scala編寫,并且緊密集成到Twitter公司自己的分布式服務Finagle中,使得跟蹤做到對應用透明。
圖3:Zipkin應用架構(gòu)圖
Zipkin的整體架構(gòu)如上圖所示,涵蓋了信息的收集、處理和展現(xiàn)。
淘寶鷹眼系統(tǒng)(EagleEye)
淘寶鷹眼是基于網(wǎng)絡調(diào)用日志的分布式跟蹤系統(tǒng),它可以分析網(wǎng)絡請求在各個分布式系統(tǒng)之間的調(diào)用情況,從而得到處理請求的調(diào)用鏈上的入口URL、應用 服務的調(diào)用關(guān)系,從而找到請求處理瓶頸,定位錯誤異常的根源位置。同時,業(yè)務方也可以在調(diào)用鏈上添加自己的業(yè)務埋點日志,使各個系統(tǒng)的網(wǎng)絡調(diào)用與實際業(yè)務 內(nèi)容得到關(guān)聯(lián)。
圖4:鷹眼系統(tǒng)的總體架構(gòu)圖