分布式環境下,實現服務端調用鏈,市面上有很多開源的框架供選擇,不過理論模型大多都是借鑒Google Dapper論文,常見的APM(Application Performance Management)組件有:
1.Zipkin
由Twitter公司開源,開放源代碼分布式的跟蹤系統,用于收集服務的定時數據,以解決微服務架構中的延遲問題,包括數據的收集、存儲、查找和展現;
github地址:https://github.com/openzipkin/zipkin
2.Pinpoint
Pinpoint是一款對Java編寫的大規模分布式系統的APM工具,由韓國人開源的分布式跟蹤組件;
github地址:https://github.com/naver/pinpoint
3.SkyWalking
是一款國人主導開發的開源應用性能監控系統,包括指標監控,分布式追蹤,分布式系統性能診斷;
github地址:https://github.com/apache/skywalking
4.CAT
CAT 是基于 Java 開發的實時應用監控平臺,為美團點評提供了全面的實時監控告警服務
github地址:https://github.com/dianping/cat
類似的還有淘寶的EgleEye,京東的Hydra等;
本人之前寫過一篇關于zipkin的快速入門文章,如下所示:
Zipkin快速開始
Zipkin是什么
Zipkin分布式跟蹤系統;它可以幫助收集時間數據,解決在microservice架構下的延遲問題;它管理這些數據的收集和查找;Zipkin的設計是基于谷歌的Google Dapper論文。每個應用程序向Zipkin報告定時數據,Zipkin UI呈現了一個依賴圖表來展示多少跟蹤請求經過了每個應用程序;如果想解決延遲問題,可以過濾或者排序所有的跟蹤請求,并且可以查看每個跟蹤請求占總跟蹤時間的百分比。
為什么使用Zipkin
隨著業務越來越復雜,系統也隨之進行各種拆分,特別是隨著微服務架構和容器技術的興起,看似簡單的一個應用,后臺可能有幾十個甚至幾百個服務在支撐;一個前端的請求可能需要多次的服務調用最后才能完成;當請求變慢或者不可用時,我們無法得知是哪個后臺服務引起的,這時就需要解決如何快速定位服務故障點,Zipkin分布式跟蹤系統就能很好的解決這樣的問題。
Zipkin下載和啟動
官方提供了三種方式來啟動,這里使用第二種方式來啟動;
wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec'java -jar zipkin.jar首先下載zipkin.jar,然后直接使用-jar命令運行,要求jdk8以上版本;
基于Undertow WEB服務器,提供對外端口:9411,可以打開瀏覽器訪問http://ip:9411
詳細參考:https://zipkin.io/pages/quickstart.html
Zipkin架構跟蹤器(Tracer)位于你的應用程序中,并記錄發生的操作的時間和元數據,提供了相應的類庫,對用戶的使用來說是透明的,收集的跟蹤數據稱為Span;將數據發送到Zipkin的儀器化應用程序中的組件稱為Reporter,Reporter通過幾種傳輸方式之一將追蹤數據發送到Zipkin收集器(collector),然后將跟蹤數據進行存儲(storage),由API查詢存儲以向UI提供數據。架構圖如下:
1.TraceZipkin使用Trace結構表示對一次請求的跟蹤,一次請求可能由后臺的若干服務負責處理,每個服務的處理是一個Span,Span之間有依賴關系,Trace就是樹結構的Span集合;
2.Span每個服務的處理跟蹤是一個Span,可以理解為一個基本的工作單元,包含了一些描述信息:id,parentId,name,timestamp,duration,annotations等,例如:
traceId:標記一次請求的跟蹤,相關的Spans都有相同的traceId;
id:span id;
name:span的名稱,一般是接口方法的名稱;
parentId:可選的id,當前Span的父Span id,通過parentId來保證Span之間的依賴關系,如果沒有parentId,表示當前Span為根Span;
timestamp:Span創建時的時間戳,使用的單位是微秒(而不是毫秒),所有時間戳都有錯誤,包括主機之間的時鐘偏差以及時間服務重新設置時鐘的可能性,出于這個原因,Span應盡可能記錄其duration;
duration:持續時間使用的單位是微秒(而不是毫秒);
annotations:注釋用于及時記錄事件;有一組核心注釋用于定義RPC請求的開始和結束;
cs:Client Send,客戶端發起請求;sr:Server Receive,服務器接受請求,開始處理;ss:Server Send,服務器完成處理,給客戶端應答;cr:Client Receive,客戶端接受應答從服務器;binaryAnnotations:二進制注釋,旨在提供有關RPC的額外信息。
3.Transport
收集的Spans必須從被追蹤的服務運輸到Zipkin collector,有三個主要的傳輸方式:HTTP, Kafka和Scribe;
4.Components
有4個組件組成Zipkin:collector,storage,search,web UI
collector:一旦跟蹤數據到達Zipkin collector守護進程,它將被驗證,存儲和索引,以供Zipkin收集器查找;
storage:Zipkin最初數據存儲在Cassandra上,因為Cassandra是可擴展的,具有靈活的模式,并在Twitter中大量使用;但是這個組件可插入,除了Cassandra之外,還支持ElasticSearch和MySQL;
search:一旦數據被存儲和索引,我們需要一種方法來提取它。查詢守護進程提供了一個簡單的JSON API來查找和檢索跟蹤,主要給Web UI使用;
web UI:創建了一個GUI,為查看痕跡提供了一個很好的界面;Web UI提供了一種基于服務,時間和注釋查看跟蹤的方法。
實戰
使用Zipkin和Brave實現http服務調用的跟蹤,Brave 是用來裝備Java程序的類庫,提供了面向標準Servlet、Spring MVC、Http Client、JAX RS、Jersey、Resteasy 和 MySQL 等接口的裝備能力,可以通過編寫簡單的配置和代碼,讓基于這些框架構建的應用可以向 Zipkin 報告數據。同時 Brave 也提供了非常簡單且標準化的接口,在以上封裝無法滿足要求的時候可以方便擴展與定制。
提供四個工程,分別對應四個服務分別是:zipkin1,zipkin2,zipkin3,zipkin4;zipkin1通過httpclient調用zipkin2,然后zipkin2通過httpclient調用zipkin3和zipkin4,形成一個調用鏈;四個服務都是基于spring-boot來實現,對應的端口分別是8081,8082,8083,8084;
1.公共maven依賴庫
2.核心類ZipkinBean提供需要使用的Bean
3.核心類ZipkinController對外接口
分別啟動四個服務,然后瀏覽器訪問:http://localhost:8081/service1,正常調用結果返回:
可以觀察zipkin web ui,查看服務的調用鏈: