Zipkin分布式系統(tǒng)調(diào)用鏈追蹤

zipkin-demo

ZIPKIN分布式系統(tǒng)調(diào)用鏈追蹤

在公司業(yè)務(wù)發(fā)展過程中悴务,剛開始的時候,我們可能比較關(guān)注單個請求的調(diào)用耗時情況适瓦,調(diào)用頻次統(tǒng)計等一些基本數(shù)據(jù)指標(biāo)土全,因為這個時候業(yè)務(wù)比較單一,系統(tǒng)相對來說較為簡單清晰蓄髓,調(diào)整和優(yōu)化起來相對來說比較容易一點叉庐。

但是隨著系統(tǒng)業(yè)務(wù)的不斷發(fā)展,需求的不斷增加会喝,整個系統(tǒng)逐漸變得越來越復(fù)雜陡叠,有可能還會涉及到外部系統(tǒng)以及公司內(nèi)部其他系統(tǒng)之間的一個交互玩郊。這個時候整個系統(tǒng)的調(diào)用鏈將會變得越來復(fù)雜(目前大多數(shù)都是分布式調(diào)用),更多的時候我們的一個前端請求可能最終需要經(jīng)過多次后端服務(wù)的調(diào)用才能得到我們想要的結(jié)果數(shù)據(jù)枉阵,而在這個過程中译红,如果調(diào)用超時或者調(diào)用變得異常的慢或者調(diào)用出現(xiàn)異常等等情況,一般情況下我們是無法準確快速得定位出這次請求出現(xiàn)的問題具體是因為那一部分出現(xiàn)了狀況引起的兴溜。

比如說具體是調(diào)用服務(wù)A出現(xiàn)了問題侦厚,還是服務(wù)B不可用亦或者是服務(wù)C調(diào)用超時等等我們是無法得知的。那這個時候就需要對整個調(diào)用鏈做一次完整的分析才能快速準確的定位出具體的問題拙徽,因而分布式調(diào)用追蹤就誕生了刨沦。

什么是分布式系統(tǒng)調(diào)用追蹤?

  1. 對多個相互協(xié)作的子系統(tǒng)之間的調(diào)用關(guān)系及依賴關(guān)系進行追蹤記錄
  2. 系統(tǒng)與系統(tǒng)之間的調(diào)用形式有多種:HTTP膘怕、RPC想诅、RMI等等
  3. 通過調(diào)用鏈的方式,將一次請求調(diào)用過程完整的串聯(lián)起來岛心,這樣就實現(xiàn)了對請求調(diào)用路徑的監(jiān)控

為什么需要進行分布式調(diào)用追蹤来破?

  1. 確定服務(wù)與服務(wù)之間的依賴關(guān)系,以便后期優(yōu)化
  2. 統(tǒng)計請求總耗時鹉梨,以及各個服務(wù)的調(diào)用耗時讳癌,以便解決系統(tǒng)瓶頸
  3. 當(dāng)請求變慢或系統(tǒng)出現(xiàn)異常時穿稳,需要盡快確定具體是哪個服務(wù)出現(xiàn)問題存皂,以便快速排查線上問題

分布式調(diào)用追蹤需要做什么?

  1. 記錄從上游到下游關(guān)鍵節(jié)點服務(wù)的日志信息逢艘,入?yún)⒌┐⒊鰠ⅰ惓6褩5刃畔?/li>
  2. 關(guān)鍵節(jié)點服務(wù)的響應(yīng)耗時
  3. 關(guān)鍵節(jié)點服務(wù)之間的依賴關(guān)系
  4. 將分散的請求串聯(lián)到一起

幾個關(guān)鍵概念

traceId:

標(biāo)識整個請求鏈它改,就是一個全局的跟蹤ID疤孕,是跟蹤的入口點,根據(jù)需求來決定在哪生成traceId央拖。比如一個http請求祭阀,首先入口是web應(yīng)用,一般看完整的調(diào)用鏈這里自然是traceId生成的起點鲜戒,結(jié)束點在web請求返回點专控,因此traceId將在這個調(diào)用鏈中進行傳遞。

spanId:

標(biāo)識一次分布式調(diào)用遏餐,這是下一層的請求跟蹤ID,這個也根據(jù)自己的需求伦腐,比如認為一次rpc,一次sql執(zhí)行等都可以是一個span失都。一個traceId包含一個以上的spanId柏蘑。

parentId:

上一次請求跟蹤ID幸冻,用來將前后的請求串聯(lián)起來。

cs:

客戶端發(fā)起請求的時間咳焚,比如dubbo調(diào)用端開始執(zhí)行遠程調(diào)用之前,標(biāo)志著Span的開始

cr:

客戶端收到處理完請求的時間,標(biāo)志著Span的結(jié)束

ss:

服務(wù)端處理完邏輯的時間

sr:

服務(wù)端收到調(diào)用端請求的時間

客戶端調(diào)用時間 = cr-cs
服務(wù)端處理時間 = sr-ss 
sr-cs:表示網(wǎng)絡(luò)延遲和時鐘抖動
ss-sr:表示服務(wù)端處理請求耗時
cr-ss:表示網(wǎng)絡(luò)延遲和時鐘抖動

Zipkin概述

Zipkin官網(wǎng):https://zipkin.io/洽损。

各個業(yè)務(wù)系統(tǒng)在相互協(xié)作調(diào)用時,將特定的跟蹤消息傳遞至zipkin黔攒,zipkin在收集到跟蹤消息之后將其進行聚合處理趁啸,存儲,展示等督惰,用戶可通過web UI方便清晰獲得網(wǎng)絡(luò)延遲不傅、調(diào)用鏈路、系統(tǒng)依賴等赏胚。

Zipkin主要涉及到四大組件

  1. Collector收集器:負責(zé)接收各service傳輸?shù)臄?shù)據(jù)
  2. Cassandra存儲器:作為Storage的一種访娶,也可以是mysql等,默認存儲在內(nèi)存里面
  3. Query查詢器:負責(zé)查詢Storage中存儲的數(shù)據(jù)信息觉阅,并且提供簡單的JSON API接口獲取數(shù)據(jù)給WEB UI使用
  4. Web UI展示器:提供簡單的web可視化界面

安裝

  1. 執(zhí)行以下命令下載jar包
wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec'
  1. 由于本身是一個spring boot項目崖疤,所以可以直接運行jar
    nohup java -jar zipkin.jar &

  2. 瀏覽器訪問:http://127.0.0.1:9411

簡單demo

  1. 新建四個工程項目:service1,service2典勇,service3劫哼,service4

  2. 它們之間的依賴關(guān)系如下:
    service1調(diào)用service2,service2調(diào)用service3和service4割笙,service3和service4互相沒有依賴权烧,直接返回。

  3. 新建4個springboot項目:

  4. pom.xml文件引入zipkin的相關(guān)坐標(biāo)依賴:

<dependency>
   <groupId>io.zipkin.brave</groupId>
   <artifactId>brave-core</artifactId>
   <version>3.9.0</version>
</dependency>

<dependency>
   <groupId>io.zipkin.brave</groupId>
   <artifactId>brave-spancollector-http</artifactId>
   <version>3.9.0</version>
</dependency>

<dependency>
   <groupId>io.zipkin.brave</groupId>
   <artifactId>brave-web-servlet-filter</artifactId>
   <version>3.9.0</version>
</dependency>

<dependency>
   <groupId>io.zipkin.brave</groupId>
   <artifactId>brave-apache-http-interceptors</artifactId>
   <version>3.9.0</version>
</dependency>

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
</dependency>

  1. 編寫zipkin配置類
@Configuration
public class ZipkinConfig {
    /**
     * 配置收集器
     * @return SpanCollector
     */
    @Bean
    public SpanCollector spanCollector(){
        Config config = HttpSpanCollector.Config.builder()
                .compressionEnabled(false)
                .connectTimeout(5000)
                .flushInterval(1)
                .readTimeout(6000)
                .build();
        return HttpSpanCollector.create("http://10.0.4.62:9411", config, new EmptySpanCollectorMetricsHandler());
    }

    /**
     * Brave各工具類的封裝
     * @param spanCollector 收集器
     * @return Brave
     */
    @Bean
    public Brave brave(SpanCollector spanCollector){
        //指定ServiceName
        Builder builder = new Builder("Zipkin-Service1");
        builder.spanCollector(spanCollector);
        //設(shè)置采集率
        builder.traceSampler(Sampler.create(1));
        return builder.build();
    }

    /**
     * 攔截器伤溉,需要serverRequestInterceptor,serverResponseInterceptor 分別完成sr和ss操作
     * @param brave
     * @return
     */
    @Bean
    public BraveServletFilter braveServletFilter(Brave brave){
        return new BraveServletFilter(brave.serverRequestInterceptor(),
                brave.serverResponseInterceptor(), new DefaultSpanNameProvider());
    }

    /**
     * httpClient客戶端般码,需要clientRequestInterceptor,clientResponseInterceptor分別完成cs和cr操作
     * @param brave
     * @return
     */
    @Bean
    public CloseableHttpClient closeableHttpClient(Brave brave){
        CloseableHttpClient httpClient = HttpClients.custom()
                .addInterceptorFirst(new BraveHttpRequestInterceptor(brave.clientRequestInterceptor(),
                        new DefaultSpanNameProvider()))
                .addInterceptorFirst(new BraveHttpResponseInterceptor(brave.clientResponseInterceptor()))
                .build();
        return httpClient;
    }
}

SpanCollector:

配置收集器。

Brave:

各工具類的封裝,其中builder.traceSampler(Sampler.ALWAYS_SAMPLE)設(shè)置采樣比率乱顾,0-1之間的百分比板祝。

BraveServletFilter:

作為攔截器,需要serverRequestInterceptor,serverResponseInterceptor 分別完成sr和ss操作

CloseableHttpClient:

添加攔截器走净,需要clientRequestInterceptor,clientResponseInterceptor 分別完成cs和cr操作,該功能由brave中的brave-okhttp模塊提供券时,同樣的道理如果需要記錄數(shù)據(jù)庫的延遲只要在數(shù)據(jù)庫操作前后完成cs和cr即可,當(dāng)然brave提供其封裝伏伯。

  1. 編寫各個項目的controller

注意事項:

  1. service1橘洞、service2、service3和service4的服務(wù)端口號需要修改成不一樣(例如:8081,8082,8083,8084)舵鳞,不然啟動會報錯震檩。

  2. ZipkinConfig配置類指定的應(yīng)用服務(wù)名稱需要改變

測試分布式追蹤

  1. 分別啟動四個服務(wù)。啟動完成之后,瀏覽器訪問:http://localhost:8081/service1

  2. 在Web UI界面即可看到調(diào)用鏈以及依賴關(guān)系:

Zipkin + Dubbo整合

基本原理:

通過編寫filter過濾器抛虏,在請求處理的前后發(fā)送日志數(shù)據(jù)博其,讓zipkin生成調(diào)用鏈數(shù)據(jù)。單獨抽離出一個項目迂猴,通過注解配置的方式實現(xiàn)調(diào)用鏈的追蹤慕淡。

  1. 編寫自動配置的注解類
  2. 編寫自動配置的實現(xiàn),主要是將特定配置節(jié)點的值讀取到上下文對象中
  3. 編寫調(diào)用追蹤配置類沸毁,主要用于配置追蹤的一些參數(shù)峰髓,zipkin地址
  4. 配置Spring自動加載
a. 在resources/META-INF目錄下創(chuàng)建spring.factories文件

b. spring.factories內(nèi)容為:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.touna.loan.trace.config.EnableTraceAutoConfiguration
  1. 追蹤上下文
  2. 創(chuàng)建Zipkin日志收集器
使用http的方式將日志信息發(fā)送給zipkin服務(wù),中間可以配合壓縮等優(yōu)化手法
  1. 日志收集器代理
使用線程池異步執(zhí)行日志發(fā)送息尺,避免阻塞正常業(yè)務(wù)邏輯

Dubbo Fillter過濾器

消費端Filter

消費端作為調(diào)用鏈的入口携兵,需要判斷是首次調(diào)用,還是內(nèi)部多次調(diào)用搂誉。如果是首次調(diào)用則生成新的traceId和spanId,如果是內(nèi)部多次調(diào)用徐紧,那么就直接從TraceContext調(diào)用鏈上下文中獲取traceId和spanId。消費端需要通過Invocation的參數(shù)列表將生成的traceId和spanId傳遞到下游系統(tǒng)中炭懊。

服務(wù)端Filter

基本與消費端的邏輯類似并级,只是這里將服務(wù)端的日志信息發(fā)送給zipkin,服務(wù)端接收消費端從Invocation的參數(shù)列表中傳遞過來的traceId和spanId侮腹,從而將整個RPC的調(diào)用邏輯串聯(lián)起來嘲碧。

Filter應(yīng)用

消費端:

1.Application啟動類開啟自動追蹤注解@EnableTraceAutoConfigurationProperties
2.配置消費端過濾器
<dubbo:consumer filter="traceConsumerFilter"/>

服務(wù)端:

1.Application啟動類啟用自動追蹤注解@EnableTraceAutoConfigurationProperties
2.配置服務(wù)端過濾器
<dubbo:provider filter="traceProviderFilter" />

Demo代碼演示:
代碼已上傳至github:git@github.com:hu1991die/zipkin-demo.git

原文參考:

  1. https://www.cnblogs.com/ASPNET2008/p/6709900.html
  2. https://t.hao0.me/devops/2016/10/15/distributed-invoke-trace.html
  3. https://www.cnblogs.com/binyue/p/5703812.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市父阻,隨后出現(xiàn)的幾起案子愈涩,更是在濱河造成了極大的恐慌,老刑警劉巖至非,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钠署,死亡現(xiàn)場離奇詭異糠聪,居然都是意外死亡荒椭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門舰蟆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趣惠,“玉大人,你說我怎么就攤上這事身害∥肚模” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵塌鸯,是天一觀的道長侍瑟。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么涨颜? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任费韭,我火速辦了婚禮,結(jié)果婚禮上庭瑰,老公的妹妹穿的比我還像新娘星持。我一直安慰自己,他們只是感情好弹灭,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布督暂。 她就那樣靜靜地躺著,像睡著了一般穷吮。 火紅的嫁衣襯著肌膚如雪逻翁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天捡鱼,我揣著相機與錄音卢未,去河邊找鬼。 笑死堰汉,一個胖子當(dāng)著我的面吹牛辽社,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翘鸭,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼滴铅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了就乓?” 一聲冷哼從身側(cè)響起汉匙,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎生蚁,沒想到半個月后噩翠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡邦投,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年伤锚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片志衣。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡屯援,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出念脯,到底是詐尸還是另有隱情狞洋,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布绿店,位于F島的核電站吉懊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜借嗽,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一怕午、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧淹魄,春花似錦郁惜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缤沦,卻和暖如春虎韵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缸废。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工包蓝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人企量。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓测萎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親届巩。 傳聞我的和親對象是個殘疾皇子硅瞧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)恕汇,斷路器腕唧,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 0 問題背景 隨著微服務(wù)架構(gòu)的流行,服務(wù)按照不同的維度進行拆分瘾英,一次請求往往需要涉及到多個服務(wù)枣接。互聯(lián)網(wǎng)應(yīng)用構(gòu)建在不...
    七寸知架構(gòu)閱讀 39,218評論 8 91
  • 2010年谷歌發(fā)表了其內(nèi)部使用的分布式跟蹤系統(tǒng)Dapper的論文講述了Dapper在谷歌內(nèi)部兩年的演變和設(shè)計缺谴、運維...
    yingyingguigui閱讀 1,787評論 0 13
  • 昨日匆匆如夢但惶,今夕渾噩難鳴。 千人萬語嘆零丁瓣赂, 只是紅塵一命榆骚。 總冀青春為伴片拍,嘗期舊好同行煌集。 二十虛度看風(fēng)輕, 不...
    乾隆詩祖閱讀 197評論 1 4
  • 好幾個星期沒有親自給女兒做飯了捌省,想著婆婆昨天的囑咐苫纤,就把雞燉了。又炒了女兒愛吃的孜然羊肉和從靈山腳下買回來的千張。...
    焦點周青閱讀 152評論 0 1