微服務(wù)監(jiān)控之分布式鏈路追蹤技術(shù) Sleuth + Zipkin

微服務(wù)監(jiān)控之分布式鏈路追蹤技術(shù) Sleuth + Zipkin

1.問(wèn)題場(chǎng)景

為了?撐?益增?的龐?業(yè)務(wù)量卦睹,我們會(huì)使?微服務(wù)架構(gòu)設(shè)計(jì)我們的系統(tǒng),使得我們的系統(tǒng)不僅能

夠通過(guò)集群部署抵擋流量的沖擊,?能根據(jù)業(yè)務(wù)進(jìn)?靈活的擴(kuò)展。

那么泣港,在微服務(wù)架構(gòu)下,?次請(qǐng)求少則經(jīng)過(guò)三四次服務(wù)調(diào)?完成价匠,多則跨越??個(gè)甚?是上百個(gè)服

務(wù)節(jié)點(diǎn)当纱。那么問(wèn)題接踵?來(lái):

1)如何動(dòng)態(tài)展示服務(wù)的調(diào)?鏈路?(?如A服務(wù)調(diào)?了哪些其他的服務(wù)---依賴關(guān)系)

2)如何分析服務(wù)調(diào)?鏈路中的瓶頸節(jié)點(diǎn)并對(duì)其進(jìn)?調(diào)優(yōu)踩窖?(?如A—>B—>C坡氯,C服務(wù)處理時(shí)間特別

?)

3)如何快速進(jìn)?服務(wù)鏈路的故障發(fā)現(xiàn)?

分布式鏈路追蹤技術(shù)

如果我們?cè)?個(gè)請(qǐng)求的調(diào)?處理過(guò)程中,在各個(gè)鏈路節(jié)點(diǎn)都能夠記錄下?志箫柳,并最終將?志進(jìn)?集

中可視化展示手形,那么我們想監(jiān)控調(diào)?鏈路中的?些指標(biāo)就有希望了~~~?如,請(qǐng)求到達(dá)哪個(gè)服務(wù)實(shí)

例悯恍?請(qǐng)求被處理的狀態(tài)怎樣库糠?處理耗時(shí)怎樣?這些都能夠分析出來(lái)了...

分布式環(huán)境下基于這種想法實(shí)現(xiàn)的監(jiān)控技術(shù)就是就是分布式鏈路追蹤(全鏈路追蹤)坪稽。

市場(chǎng)上的分布式鏈路追蹤?案

分布式鏈路追蹤技術(shù)已然成熟曼玩,產(chǎn)品也不少鳞骤,國(guó)內(nèi)外都有窒百,?如

Spring Cloud Sleuth + Twitter Zipkin

阿?巴巴的“鷹眼”

?眾點(diǎn)評(píng)的“CAT”

美團(tuán)的“Mtrace”

京東的“Hydra”

新浪的“Watchman”

另外還有最近也被提到很多的Apache Skywalking。

2.分布式鏈路追蹤技術(shù)核?思想

本質(zhì):記錄?志

為了追蹤整個(gè)調(diào)?鏈路豫尽,肯定需要記錄?志篙梢,?志記錄是基礎(chǔ),在此之上肯定有?些理論概念美旧,當(dāng)下主

流的的分布式鏈路追蹤技術(shù)/系統(tǒng)所基于的理念都來(lái)?于Google的?篇論?《Dapper, a Large-Scale

Distributed Systems Tracing Infrastructure》,核?理念如下:

Trace:服務(wù)追蹤的追蹤單元是從客戶發(fā)起請(qǐng)求(request)抵達(dá)被追蹤系統(tǒng)的邊界開(kāi)始渤滞,到被追蹤系統(tǒng)

向客戶返回響應(yīng)(response)為?的過(guò)程

Trace ID:為了實(shí)現(xiàn)請(qǐng)求跟蹤,當(dāng)請(qǐng)求發(fā)送到分布式系統(tǒng)的??端點(diǎn)時(shí)榴嗅,只需要服務(wù)跟蹤框架為該請(qǐng)求

創(chuàng)建?個(gè)唯?的跟蹤標(biāo)識(shí)Trace ID妄呕,同時(shí)在分布式系統(tǒng)內(nèi)部流轉(zhuǎn)的時(shí)候,框架失蹤保持該唯?標(biāo)識(shí)嗽测,直

到返回給請(qǐng)求?

?個(gè)Trace由?個(gè)或者多個(gè)Span組成绪励,每?個(gè)Span都有?個(gè)SpanId,Span中會(huì)記錄TraceId唠粥,同時(shí)還有

?個(gè)叫做ParentId疏魏,指向了另外?個(gè)Span的SpanId,表明??關(guān)系晤愧,其實(shí)本質(zhì)表達(dá)了依賴關(guān)系

Span ID:為了統(tǒng)計(jì)各處理單元的時(shí)間延遲大莫,當(dāng)請(qǐng)求到達(dá)各個(gè)服務(wù)組件時(shí),也是通過(guò)?個(gè)唯?標(biāo)識(shí)Span

ID來(lái)標(biāo)記它的開(kāi)始官份,具體過(guò)程以及結(jié)束只厘。對(duì)每?個(gè)Span來(lái)說(shuō),它必須有開(kāi)始和結(jié)束兩個(gè)節(jié)點(diǎn)舅巷,通過(guò)記錄

開(kāi)始Span和結(jié)束Span的時(shí)間戳羔味,就能統(tǒng)計(jì)出該Span的時(shí)間延遲,除了時(shí)間戳記錄之外悄谐,它還可以包含

?些其他元數(shù)據(jù)介评,?如時(shí)間名稱、請(qǐng)求信息等。

每?個(gè)Span都會(huì)有?個(gè)唯?跟蹤標(biāo)識(shí) Span ID,若?個(gè)有序的 span 就組成了?個(gè) trace们陆。

Span可以認(rèn)為是?個(gè)?志數(shù)據(jù)結(jié)構(gòu)寒瓦,在?些特殊的時(shí)機(jī)點(diǎn)會(huì)記錄了?些?志信息,?如有時(shí)間戳坪仇、

spanId杂腰、TraceId,parentIde等椅文,Span中也抽象出了另外?個(gè)概念喂很,叫做事件,核?事件如下

CS :client send/start 客戶端/消費(fèi)者發(fā)出?個(gè)請(qǐng)求皆刺,描述的是?個(gè)span開(kāi)始

SR: server received/start 服務(wù)端/?產(chǎn)者接收請(qǐng)求 SR-CS屬于請(qǐng)求發(fā)送的?絡(luò)延遲

SS: server send/fifinish 服務(wù)端/?產(chǎn)者發(fā)送應(yīng)答 SS-SR屬于服務(wù)端消耗時(shí)間

CR:client received/fifinished 客戶端/消費(fèi)者接收應(yīng)答 CR-SS表示回復(fù)需要的時(shí)間(響應(yīng)的?絡(luò)延

遲)


Spring Cloud Sleuth (追蹤服務(wù)框架)可以追蹤服務(wù)之間的調(diào)?少辣,Sleuth可以記錄?個(gè)服務(wù)請(qǐng)求經(jīng)過(guò)哪

些服務(wù)、服務(wù)處理時(shí)?等羡蛾,根據(jù)這些漓帅,我們能夠理清各微服務(wù)間的調(diào)?關(guān)系及進(jìn)?問(wèn)題追蹤分析。

耗時(shí)分析:通過(guò) Sleuth 了解采樣請(qǐng)求的耗時(shí)痴怨,分析服務(wù)性能問(wèn)題(哪些服務(wù)調(diào)??較耗時(shí))

鏈路優(yōu)化:發(fā)現(xiàn)頻繁調(diào)?的服務(wù)忙干,針對(duì)性優(yōu)化等

Sleuth就是通過(guò)記錄?志的?式來(lái)記錄蹤跡數(shù)據(jù)的

注意:我們往往把Spring Cloud SleuthZipkin ?起使?,把 Sleuth 的數(shù)據(jù)信息發(fā)送給 Zipkin 進(jìn)

?聚合浪藻,利? Zipkin 存儲(chǔ)并展示數(shù)據(jù)捐迫。

3. Sleuth + Zipkin

1)每?個(gè)需要被追蹤蹤跡的微服務(wù)?程都引?依賴坐標(biāo)

<!--鏈路追蹤-->
<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

2)每?個(gè)微服務(wù)都修改application.yml配置?件,添加?志級(jí)別

#分布式鏈路追蹤
logging:
 level:
 org.springframework.web.servlet.DispatcherServlet: debug
 org.springframework.cloud.sleuth: debug

3)結(jié)合 Zipkin 展示追蹤數(shù)據(jù)

Zipkin 包括Zipkin Server和 Zipkin Client兩部分爱葵,Zipkin Server是?個(gè)單獨(dú)的服務(wù)施戴,Zipkin Client就是具體的微服務(wù)

  1. Zipkin Server 構(gòu)建

    <!--zipkin-server的依賴坐標(biāo)-->
     <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-server</artifactId>
        <version>2.12.3</version>
     <exclusions>
     <!--排除掉log4j2的傳遞依賴,避免和springboot依賴的?志組件沖突-->
     <exclusion>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
     </exclusion>
     </exclusions>
     </dependency>
     <!--zipkin-server ui界?依賴坐標(biāo)-->
     <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-autoconfigure-ui</artifactId>
        <version>2.12.3</version>
     </dependency>
    
  1. 添加注解啟動(dòng)

    @EnableZipkinServer

  2. 添加配置

    management:
      metrics:
       web:
         server:
           auto-time-requests: false # 關(guān)閉?動(dòng)檢測(cè)請(qǐng)求
    
  1. Zipkin Client 構(gòu)建

    <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-zipkin</artifactId>
    </dependency>
    
  1. 配置:添加對(duì)zipkin server的引?

    spring:
      zipkin:
        base-url: http://127.0.0.1:9411 # zipkin server的請(qǐng)求地址
        sender:
     # web 客戶端將蹤跡?志數(shù)據(jù)通過(guò)?絡(luò)請(qǐng)求的?式傳送到服務(wù)端钧惧,另外還有配置
     # kafka/rabbit 客戶端將蹤跡?志數(shù)據(jù)傳遞到mq進(jìn)?中轉(zhuǎn)
        type: web
     sleuth:
       sampler:
     # 采樣率 1 代表100%全部采集 暇韧,默認(rèn)0.1 代表10% 的請(qǐng)求蹤跡數(shù)據(jù)會(huì)被采集
     # ?產(chǎn)環(huán)境下,請(qǐng)求量?常?浓瞪,沒(méi)有必要所有請(qǐng)求的蹤跡數(shù)據(jù)都采集分析懈玻,對(duì)于?絡(luò)包括server端壓?都是?較?的,可以配置采樣率采集?定?例的請(qǐng)求的蹤跡數(shù)據(jù)進(jìn)?分析即可
       probability: 1
    

3.1 Zipkin持久化到mysql

  1. 引入依賴

    <dependency>
     <groupId>io.zipkin.java</groupId>
     <artifactId>zipkin-autoconfigure-storage?mysql</artifactId>
     <version>2.12.3</version>
     </dependency>
     <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     </dependency>
     <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
     <version>1.1.10</version>
     </dependency>
     <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-tx</artifactId>
     </dependency>
     <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
     </dependency>
    
  1. 配置yaml

    # 指定zipkin持久化介質(zhì)為mysql
    zipkin:
      storage:
        type: mysql
    
  1. 啟動(dòng)類中注?事務(wù)管理器

    @Bean
    public PlatformTransactionManager txManager(DataSource dataSource) {
     return new DataSourceTransactionManager(dataSource);
    }
    
    1. 初始數(shù)據(jù)庫(kù)腳本
    CREATE TABLE IF NOT EXISTS zipkin_spans (
     `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this
    means the trace uses 128 bit traceIds instead of 64 bit',
     `trace_id` BIGINT NOT NULL,
     `id` BIGINT NOT NULL,
     `name` VARCHAR(255) NOT NULL,
     `remote_service_name` VARCHAR(255),
     `parent_id` BIGINT,
     `debug` BIT(1),
     `start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for
    endTs query and to implement TTL',
     `duration` BIGINT COMMENT 'Span.duration(): micros used for
    minDuration and maxDuration query',
     PRIMARY KEY (`trace_id_high`, `trace_id`, `id`)
    ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE
    utf8_general_ci;
    ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`)
    COMMENT 'for getTracesByIds';
    ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and
    getSpanNames';
    ALTER TABLE zipkin_spans ADD INDEX(`remote_service_name`) COMMENT 'for
    getTraces and getRemoteServiceNames';
    ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces
    ordering and range';
    CREATE TABLE IF NOT EXISTS zipkin_annotations (
     `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this
    means the trace uses 128 bit traceIds instead of 64 bit',
     `trace_id` BIGINT NOT NULL COMMENT 'coincides with
    zipkin_spans.trace_id',
     `span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',
     `a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or
    Annotation.value if type == -1',
     `a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be
    smaller than 64KB',
     `a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if
    Annotation',
     `a_timestamp` BIGINT COMMENT 'Used to implement TTL;
    Annotation.timestamp or zipkin_spans.timestamp',
     `endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is
    null',
     `endpoint_ipv6` BINARY(16) COMMENT 'Null when
    Binary/Annotation.endpoint is null, or no IPv6 address',
     `endpoint_port` SMALLINT COMMENT 'Null when
    Binary/Annotation.endpoint is null',
     `endpoint_service_name` VARCHAR(255) COMMENT 'Null when
    Binary/Annotation.endpoint is null'
    ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE
    utf8_general_ci;
    ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`,
    `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert
    on duplicate';
    ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`,
    `span_id`) COMMENT 'for joining with zipkin_spans';
    ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`)
    COMMENT 'for getTraces/ByIds';
    ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`)
    COMMENT 'for getTraces and getServiceNames';
    ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for
    getTraces and autocomplete values';
    ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for
    getTraces and autocomplete values';
    ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`,
    `a_key`) COMMENT 'for dependencies job';
    CREATE TABLE IF NOT EXISTS zipkin_dependencies (
     `day` DATE NOT NULL,
     `parent` VARCHAR(255) NOT NULL,
     `child` VARCHAR(255) NOT NULL,
     `call_count` BIGINT,
     `error_count` BIGINT,
     PRIMARY KEY (`day`, `parent`, `child`)
    ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE
    utf8_general_ci;
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乾颁,一起剝皮案震驚了整個(gè)濱河市涂乌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌英岭,老刑警劉巖湾盒,帶你破解...
    沈念sama閱讀 222,946評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诅妹,居然都是意外死亡罚勾,警方通過(guò)查閱死者的電腦和手機(jī)毅人,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)尖殃,“玉大人丈莺,你說(shuō)我怎么就攤上這事∷头幔” “怎么了缔俄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,716評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)器躏。 經(jīng)常有香客問(wèn)我俐载,道長(zhǎng),這世上最難降的妖魔是什么登失? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,222評(píng)論 1 300
  • 正文 為了忘掉前任遏佣,我火速辦了婚禮,結(jié)果婚禮上壁畸,老公的妹妹穿的比我還像新娘贼急。我一直安慰自己,他們只是感情好捏萍,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著空闲,像睡著了一般令杈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碴倾,一...
    開(kāi)封第一講書(shū)人閱讀 52,807評(píng)論 1 314
  • 那天逗噩,我揣著相機(jī)與錄音,去河邊找鬼跌榔。 笑死异雁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的僧须。 我是一名探鬼主播纲刀,決...
    沈念sama閱讀 41,235評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼担平!你這毒婦竟也來(lái)了示绊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,189評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤暂论,失蹤者是張志新(化名)和其女友劉穎面褐,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體取胎,經(jīng)...
    沈念sama閱讀 46,712評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡展哭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匪傍。...
    茶點(diǎn)故事閱讀 40,926評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡坝咐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出析恢,到底是詐尸還是另有隱情墨坚,我是刑警寧澤,帶...
    沈念sama閱讀 36,580評(píng)論 5 351
  • 正文 年R本政府宣布映挂,位于F島的核電站泽篮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏柑船。R本人自食惡果不足惜帽撑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鞍时。 院中可真熱鬧亏拉,春花似錦、人聲如沸逆巍。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,750評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锐极。三九已至笙僚,卻和暖如春损晤,著一層夾襖步出監(jiān)牢的瞬間限煞,已是汗流浹背悠咱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,867評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工耍贾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赌朋,地道東北人巷帝。 一個(gè)月前我還...
    沈念sama閱讀 49,368評(píng)論 3 379
  • 正文 我出身青樓叨咖,卻偏偏與公主長(zhǎng)得像像啼,于是被迫代替她去往敵國(guó)和親汪榔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蒲拉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評(píng)論 2 361