Brave接入ZipKin實(shí)現(xiàn)調(diào)用鏈跟蹤【上】

導(dǎo)讀:

一個(gè)分布式系統(tǒng)由若干分布式服務(wù)構(gòu)成,每一個(gè)請(qǐng)求會(huì)經(jīng)過(guò)多個(gè)業(yè)務(wù)系統(tǒng)并留下足跡,但是這些分散的數(shù)據(jù)對(duì)于問(wèn)題排查,或是流程優(yōu)化都很有限,要能做到追蹤每個(gè)請(qǐng)求的完整鏈路調(diào)用,收集鏈路調(diào)用上每個(gè)服務(wù)的性能數(shù)據(jù),計(jì)算性能數(shù)據(jù)和比對(duì)性能指標(biāo)(SLA),甚至能夠再反饋到服務(wù)治理中,那么這就是分布式跟蹤的目標(biāo)。在業(yè)界:淘寶的鷹眼, 京東的Hydra實(shí)現(xiàn)了這個(gè)目標(biāo),這里要介紹的是twitter 的 zipkin。

ZipKin介紹

1、ZipKin簡(jiǎn)介

1、Zipkin是一個(gè)致力于收集分布式服務(wù)的時(shí)間數(shù)據(jù)的分布式跟蹤系統(tǒng)。

2、Zipkin 主要涉及四個(gè)組件:collector(數(shù)據(jù)采集),storage(數(shù)據(jù)存儲(chǔ)),search(數(shù)據(jù)查詢),UI(數(shù)據(jù)展示)。

3、github源碼地址:https://github.com/openzipkin/zipkin。

4、Zipkin提供了可插拔數(shù)據(jù)存儲(chǔ)方式:In-Memory,MySql, Cassandra, Elasticsearch;本文為了測(cè)試方便以In-Memory方式進(jìn)行存儲(chǔ),個(gè)人推薦Elasticsearch,關(guān)于更多的存儲(chǔ)方式可以參考github。

5、ZipKin運(yùn)行環(huán)境需要Jdk8支持。

6、下載并啟動(dòng)ZipKin:

下載并規(guī)劃成如下目錄結(jié)構(gòu),可以自行更改。

說(shuō)明:bin目錄為啟動(dòng)腳本所在目錄,lib目錄為zipkin-server jar所在目錄。

附下Jdk8下啟動(dòng)腳本,存儲(chǔ)方式不是本篇重點(diǎn),要更換存儲(chǔ)方式請(qǐng)參考github。

運(yùn)行時(shí)參數(shù):

通過(guò)http://XXX:9411就可以訪問(wèn)zipkin UI控制臺(tái)

2、ZipKin數(shù)據(jù)模型

Trace:一組代表一次用戶請(qǐng)求所包含的spans,其中根span只有一個(gè)。

Span: 一組代表一次HTTP/RPC請(qǐng)求所包含的annotations。

annotation:包括一個(gè)值,時(shí)間戳,主機(jī)名(留痕跡)。

3?ZipKin生成調(diào)用鏈

把一些輕量級(jí)的TraceID和Span ID在服務(wù)之間傳遞,服務(wù)之間將信息報(bào)告給Zipkin,ZipKin將服務(wù)之間調(diào)用關(guān)系有效組成一個(gè)完整的調(diào)用鏈。

注:TraceId:全局ID, spanId-每個(gè)方法調(diào)用的id,parentSpanId-父SpanId, sampled-是否需要采樣。

1、 客戶端:

客戶端需要把Trace(traceId,spanId,parentSpanId,sampled)信息放在Request/ThreadLocal中。

如果需要進(jìn)行HTTP/RPC調(diào)用,需要把Trace的信息放在協(xié)議中,例如http header/Rpc Extraparams。

2、 服務(wù)端:

檢查http header/Rpc Extraparams中是否存在Trace信息,如果存在就把這些信息取出來(lái),然后存入到Request/ThreadLocal中,進(jìn)而把請(qǐng)求串接起來(lái)。如果不存在,那么就開(kāi)始一個(gè)新的Trace。

?Brave介紹

1、?Brave簡(jiǎn)介

Brave 是用來(lái)裝備 Java 程序的類庫(kù),提供了面向標(biāo)準(zhǔn)Servlet、Spring MVC、Http Client、JAX RS、Jersey、Resteasy 和 MySQL 等接口的裝備能力,可以通過(guò)編寫簡(jiǎn)單的配置和代碼,讓基于這些框架構(gòu)建的應(yīng)用可以向 Zipkin 報(bào)告數(shù)據(jù)。同時(shí) Brave 也提供了非常簡(jiǎn)單且標(biāo)準(zhǔn)化的接口,在以上封裝無(wú)法滿足要求的時(shí)候可以方便擴(kuò)展與定制。

雖然Brave提供了默認(rèn)的實(shí)現(xiàn),結(jié)合項(xiàng)目實(shí)際情況,基本上是需要定制才能滿足要求的,本文針對(duì)默認(rèn)實(shí)現(xiàn)就不再啰嗦,直接針對(duì)定制進(jìn)行講解。

由于項(xiàng)目中用到SpringMvc,HttpClient,Jprotobuf-Rpc-Socket,本文主要介紹針對(duì)SpringMvc,HttpClient,Jprotobuf-Rpc-Socket的擴(kuò)展與定制。

2、服務(wù)調(diào)用常用的兩種方式

1、服務(wù)以Http方式提供Rest接口,服務(wù)與服務(wù)之間通過(guò)HttpClient互相調(diào)用,對(duì)外以Http方式提供Rest接口,這里Rest以SpringMvc為例。

2、服務(wù)以jprotobufrpcsocket方式提供Rpc接口,服務(wù)與服務(wù)之間通過(guò)RPC互相調(diào)用,對(duì)外以Http方式提供Rest接口,這里Rest以SpringMvc為例,RPC以jprotobufrpcsocket為例。

3、Brave環(huán)境準(zhǔn)備

1、Maven引入

2、通過(guò)實(shí)現(xiàn)FactoryBean接口,創(chuàng)建Brave實(shí)例,同時(shí)為Brave實(shí)例設(shè)置Http采集器,默認(rèn)采用日志打印方式。

FactoryBean:

注:FactoryBean的作用在于更靈活創(chuàng)建Brave實(shí)例,serviceName為對(duì)應(yīng)用服務(wù)的名稱,ZipkinSetting為HttpSpanCollector實(shí)例需要的參數(shù)配置,以Http方式采集數(shù)據(jù),就需要例如超時(shí)時(shí)間等這樣的參數(shù)配置。

ZipkinSetting:

Brave環(huán)境的準(zhǔn)備就講到這里了。

4、HttpClient裝配

Brave默認(rèn)提供了OkHttpClient的支持,但是對(duì)于一個(gè)完成了的項(xiàng)目來(lái)說(shuō)并不合適,因此我需要對(duì)HttpClient定制,對(duì)Http請(qǐng)求增加攔截功能,能在請(qǐng)求前后埋點(diǎn)。

1、HttpInvokeInteceptor:這個(gè)接口的作用在通過(guò)HttpClient請(qǐng)求前和請(qǐng)求后埋點(diǎn)。

2、HTTPClient:這個(gè)類的作用在于每次請(qǐng)求都會(huì)調(diào)用HttpClient execute方法,因此在execute方法體,我們可以在請(qǐng)求前和請(qǐng)求后埋點(diǎn)實(shí)現(xiàn)鏈路跟蹤;在這個(gè)類持有HttpInvokeInteceptor的引用,完成請(qǐng)求前和請(qǐng)求后攔截。

3、HTTPRequest:這個(gè)類是POST,GET,DELETE,PUT等請(qǐng)求的父類,這里定義了URL和Method,以便在請(qǐng)求前埋點(diǎn)處留下更清晰的足跡,目的在于在Zipkin能留下url,method信息。

4、HTTPResponse:請(qǐng)求返回?cái)?shù)據(jù),在獲取到HTTPResponse以后用來(lái)在請(qǐng)求完成后埋點(diǎn)留下更清晰的足跡。

5、FormPost:HTTPRequest的子類,真實(shí)的請(qǐng)求類。

6、BraveHttpClientInteceptor:BraveHttpClientInteceptor是HttpInvokeInteceptor的實(shí)現(xiàn)類,真實(shí)的HttpClient裝配的實(shí)現(xiàn)。

請(qǐng)求前通過(guò)實(shí)現(xiàn)ClientRequestAdapter接口,請(qǐng)求后通過(guò)實(shí)現(xiàn)ClientResponseAdapter接口完成定制。

以上完成了HttpClient的裝配。

5、SpringMvc裝配

Brave庫(kù)本身提供了SpringMVC攔截器針對(duì)Controller處理前后埋點(diǎn)的支持,接下來(lái)這是在此基礎(chǔ)上做了改寫:

讓埋點(diǎn)信息更完善

增加了訪問(wèn)記錄采集,有了訪問(wèn)記錄,為服務(wù)治理做好準(zhǔn)備(服務(wù)治理不作為講解的范疇)

BraveHttpServerInterceptor:SpringMvc標(biāo)準(zhǔn)攔截器,主要用于在Controller處理前和處理后埋點(diǎn)實(shí)現(xiàn)請(qǐng)求跟蹤。主要用于Server端裝配。

6、JprotobufRpcSocket裝配

1、版本選擇:JprotobufRpcSocket3.4.4

2、JprotobufRpcSocket3.4.4 BUG: 客戶端攔截器不生效。

原因:

HaProtobufRpcProxyBean繼承HaProtobufRpcProxy,HaProtobufRpcProxy的onBuildProtobufRpcProxy方法如下:

HaProtobufRpcProxyBean有對(duì)該方法重寫,重寫的方法如下:

方法重寫以后對(duì)應(yīng)的攔截器沒(méi)有往下傳,導(dǎo)致攔截器不可用,這個(gè)bug修復(fù)如果通過(guò)修改源代碼的方式比較麻煩,建議在項(xiàng)目中按照下面方式修改,不會(huì)涉及到Jprotobuf-Rpc-Socket依賴的更改與管理。

FIX:

Fix后的代碼結(jié)構(gòu)如下:

保持包名不變,對(duì)HaProtobufRpcProxyBean更名為MatrixHaProtobufRpcProxyBean ,HaProtobufRpcProxy更名為MatrixHaProtobufRpcProxy,HaRpcProxyFactoryBean更名為MatrixHaRpcProxyFactoryBean。

MatrixHaRpcProxyFactoryBean代碼做如下改動(dòng):

MatrixHaProtobufRpcProxy代碼做如下改動(dòng):

MatrixHaProtobufRpcProxyBean將攔截器往下傳,代碼做如下改動(dòng):

MatrixHaProtobufRpcProxy繼承NamingServiceChangeListener取代HaProtobufRpcProxy。

在客戶端使用的時(shí)候通過(guò)MatrixHaRpcProxyFactoryBean取代HaRpcProxyFactoryBean創(chuàng)建接口代理。

3、JprotobufRpcSocket3.4.4 Extraparams坑: Jprotobuf-Rpc-Socket 攔截器InvokerInterceptor可以通過(guò)MethodInvocation以Aop的方式往服務(wù)端傳值。

需要通過(guò)SerializationUtils序列化與反序列化。

序列化的數(shù)據(jù)結(jié)構(gòu)需要是Map。

查看RemoteExcuteInvokeRpcHandler 82行源代碼發(fā)現(xiàn):有通過(guò)SerializationUtils反序列化并且強(qiáng)轉(zhuǎn)為MAP:

4、RPC裝配源碼介紹:RpcPrepareInteceptor

RpcPrepareInteceptor: BraveRpcClientInterceptor與BraveRpcServerInteceptor的父類。

BraveServerRequest, BraveClientRequest,BraveServerResponse,BraveClientResponse ? RPC擴(kuò)展點(diǎn)。

5、RPC客戶端裝配BraveRpcClientInterceptor源碼介紹:

6、RPC服務(wù)端裝配BraveRpcServerInteceptor源碼介紹:

未完待續(xù)~~~

本文作者:秦瑜 Chris.Qin(點(diǎn)融黑幫),來(lái)自點(diǎn)融BE Team,2015年10月加入點(diǎn)融,負(fù)責(zé)多個(gè)項(xiàng)目的架構(gòu)與設(shè)計(jì),多年大并發(fā)分布式互聯(lián)網(wǎng)架構(gòu)經(jīng)驗(yàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,699評(píng)論 19 139
  • 在上篇《Brave接入ZipKin實(shí)現(xiàn)調(diào)用鏈跟蹤【上】》中,我們了解了ZipKin和Brave的相關(guān)知識(shí)及配置,本...
    點(diǎn)融黑幫閱讀 4,111評(píng)論 1 11
  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。。。 其實(shí)如果沒(méi)有APIManager這一層是沒(méi)法使用delegate的,畢竟多個(gè)單...
    yhtang閱讀 5,494評(píng)論 1 23
  • 家有2歲9個(gè)月男寶一枚,然媽家教手記持續(xù)更新中。 被推了一把 帶然然在樓下玩兒,遠(yuǎn)遠(yuǎn)看到天佑?jì)寢寧е煊舆^(guò)來(lái)了。天...
    然媽Miya閱讀 340評(píng)論 6 3
  • 許久了,想說(shuō)一說(shuō)我的婆婆。 踏進(jìn)老公家門前,不曾丁點(diǎn)兒了解那個(gè)叫“婆婆”的人,會(huì)對(duì)“媳婦”的日子產(chǎn)生什么影...
    丁一嵐閱讀 1,165評(píng)論 9 8

友情鏈接更多精彩內(nèi)容