天天看點

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

在單體服務的架構中,所有的服務,元件都在一台機器上,如果需要監控服務的異常與耗時,往往是比較簡單的。我們可以使用 AOP 在調用具體的業務邏輯前後分别列印一下時間即可計算出整體的調用時間。在問題追蹤的時候,也可以在關鍵節點列印日志。

但是在微服務架構裡就不同了,一次請求會涉及到多個子產品與系統,往往需要多台機器的互相協作才能完成。而一系列的請求,不僅會涉及到串聯并聯、還有同步異步之分。這個時候,如果依然采取單體架構中服務監控的方式,那麼确定這個請求背後調用了哪些服務,哪些子產品,哪些節點及調用的先後順序,調用的耗時,或者追蹤調用中出現的問題甚至會讓開發人員當場去世。于是乎,我們馬上就會想到服務追蹤系統。

要實作服務追蹤,我們有三點問題需要解決:

1、埋點并收集服務調用的上下文資料。

2、對收集到的資料進行分析、實時處理。

3、資料鍊路的可視化展示。

通過分布式追蹤系統能很好地定位如下請求的每條具體請求鍊路,進而輕易地實作請求鍊路追蹤:

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

那麼,有沒有一種規範能讓大家都很好的進行鍊路追蹤系統的開發呢?

為了解決不同的分布式追蹤系統 API 不相容的問題,誕生了 OpenTracing 規範,OpenTracing 是一個輕量級的标準化層,它位于應用程式/類庫和追蹤或日志分析程式之間。

Opentracing是分布式鍊路追蹤的一種規範标準,具有平台無關的特性,開發者隻需修改少量的配置代碼,就可以在符合Opentracing标準的鍊路追蹤系統之間自由切換。

被跟蹤的服務隻需要調用Opentracing接口,就可以被任何實作這套接口的跟蹤背景(比如Zipkin, Jaeger等等)支援,而作為一個跟蹤背景,隻要實作了個這套接口,就可以跟蹤到任何調用這套接口的服務。同時,Opentracing對程序間跟蹤資料傳遞與追蹤的最小獨立機關Span進行了标準化。

1、Span

Span是一條追蹤鍊路中的基本組成要素,也是最小獨立機關。一個span表示一個獨立的工作單元,比如可以表示一次函數調用,一次http請求等等。

span中包含以下資訊:

服務名稱(調用請求的名字)

服務的開始時間和結束時間

K/V形式的Tags

K/V形式的截斷日志Logs

SpanContext(span上下文資訊,其中包含 Trace ID 和 Span ID)

References:該span對一個或多個span的引用(通過引用SpanContext來擷取)。

2、Trace

一個完整請求鍊路,每個調用鍊由多個 Span 組成。

3、SpanContext

Trace 的全局上下文資訊, 如裡面有包含着traceId。

大家可以看我這張圖來了解資料結構,一次請求的完整請求完整就是一個Trace, 顯然對于這個請求來說,必須要有一個全局辨別來辨別這一個請求TraceId,每一次調用就稱為一個 Span每一次調用都要帶上全局的TraceId和自身的SpanId, 這樣才可把全局 TraceId 與每個調用關聯起來。

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

了解到OpenTracing的資料結構之後。我們首先要收集服務Tacre的資料。

與單體服務中采用埋點的方式不同,現在主流的zipkin和SkyWalking采用了不同的方法收集服務鍊路的資料:

zipkin :攔截請求,發送(HTTP,MQ)資料至zipkin服務,需要的話可以持久化到資料庫。

SkyWalking:使用 agent的形式去接入業務系統,這樣就不需要在業務系統裡添加任何的日志代碼,也能記錄到對應的調用資料庫。

收集到的資料的内容如下圖所示:

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

如果對每個請求調用都采集,那毫無疑問資料量會非常大。對于已經上線的服務而言,每一次請求的情況都是差不多的(如果出現異常報錯當然另說)。其實沒有必要對每個請求都采集,我們可以設定采樣頻率,隻采樣部分資料,SkyWalking中就預設設定了3秒隻采樣三次。這樣的頻率其實足夠我們分析性能了(小聲哔哔:其實大多數業務根本沒有那麼多的請求)。同時,為了保證全局一緻性,上遊服務采樣了(SpanContext有說明),那麼下遊服務一定也需要采樣,不然很有可能出現不一緻的情況。

得到這些資料以後,對鍊路資料進行可視化展示就能實作服務追蹤了。

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

Zipkin是一款開源的分布式實時資料追蹤系統,基于Google Dapper的論文設計而來,由Twitter公司開發貢獻,它的架構圖如下:

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

但是光有Zipkin還不夠,Spring Cloud為我們提供了Sleuth這個元件,它可以為服務之間調用提供錯誤補貨,耗時分析和鍊路追蹤。

Spring Cloud Sleuth可以結合Zipkin,将資訊發送到Zipkin,利用Zipkin的存儲來存儲資訊,利用Zipkin Ui來展示資料(Sleuth 預設采用 Http 方式将 span 傳輸給 Zipkin)。

基于springboot來搭建zipkin還是比較簡單的事情,在生成子產品的時候已經有了完整的腳手架,隻需要在maven(或者gradle等任何倉庫)放上對應的依賴就行。

為什麼選擇 RabbitMQ 消息中間件發送 span 資訊

sleuth 預設采用 http 通信方式,将資料傳給 zipkin 作頁面渲染,但是 http 傳輸過程中如果由于不可抗因素導緻 http 通信中斷,那麼此次通信的資料将會丢失。但是使用RabbitMQ的話,消息隊列可以積壓千萬級别的消息,下次重連之後依然可以可以繼續消費。随着線程增多,并發量提升之後,RabbitMQ 異步發送資料明顯更具有優勢。同時,RabbitMQ 支援消息、隊列持久化,可以通過消息狀态落庫、重回隊列、鏡像隊列等技術手段保證其高可用。具體可以參考RabbitMQ原理。

除了依賴方面,在yaml中,zipkin這樣配置

在使用 Spring Boot 2.x 版本後,官方就不推薦自行定制編譯了,讓我們直接使用編譯好的 jar 包。是以我們在使用@EnableZipkinServer或@EnableZipkinStreamServer注解的時候要注意搭配好springboot的版本。

搭建完畢以後,我們可以登入 http://localhost:9411/zipkin/ 位址進入zipkin的首頁:

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

點選Find Traces就能看到較為簡潔的顯示Span的個數以及調用總時延。

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

我們進入一個完整的調用鍊後通路其中的一個節點得到以下資料:

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

然後在Dependencies的選項中能看到調用鍊路的圖,當然,因為測試的原因,并沒有建立很複雜的調用鍊路。

【進階之路】調用鍊監控原理與zipkin項目簡單搭建

從這一塊我們能夠感覺到,springcloud對zipkin的內建非常友好,不用另外啟動什麼jar包,可以直接內建在springcloud的環境中,這也是我選擇用zipkin作為展示的原因。

Zipkin是Twitter開源的調用鍊分析工具,目前基于springcloud sleuth得到了廣泛的使用,特點是輕量,使用部署簡單。

除此之外還有:

SkyWalking 本土開源的基于位元組碼注入的調用鍊分析,以及應用監控分析工具。特點是支援多種插件,UI功能較強,接入端無代碼侵入。目前已加入Apache孵化器。

Pinpoint 南韓人開源的基于位元組碼注入的調用鍊分析,以及應用監控分析工具。特點是支援多種插件,UI功能強大,接入端無代碼侵入。

CAT 大衆點評開源的基于編碼和配置的調用鍊分析,應用監控分析,日志采集,監控報警等一系列的監控平台工具。

類别

Zipkin

SkyWalking

Pinpoint

CAT

實作方式

攔截請求,發送(HTTP,mq)資料至zipkin服務

java探針,位元組碼增強

代碼埋點(攔截器,注解,過濾器等)

接入方式

基于linkerd或者sleuth方式,引入配置即可

javaagent位元組碼

代碼侵入

http,MQ

gRPC

thrift

http/tcp

資料存儲

ES,mysql,Cassandra,記憶體

ES,H2

Hbase

mysql,hdfs

顆粒度

接口級

方法級

代碼級

社群活躍度

至于開發選型的問題,大家可以根據自己的産品實際選擇适合的鍊路追蹤系統,可以參考這篇知乎文章監控系統比較 Skywalking Pinpoint Cat zipkin

大家好,我是練習java兩年半時間的南橘,下面是我的微信,需要之前的導圖或者想互相交流經驗的小夥伴可以一起互相交流哦。
【進階之路】調用鍊監控原理與zipkin項目簡單搭建