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