使用sleuth實(shí)現(xiàn)微服務(wù)跟蹤

sleuth原理圖.png

在微服務(wù)架構(gòu)中,眾多的微服務(wù)之間互相調(diào)用蜂怎,如何清晰地記錄服務(wù)的調(diào)用鏈路是一個(gè)需要解決的問(wèn)題囊嘉。同時(shí),由于各種原因识椰,跨進(jìn)程的服務(wù)調(diào)用失敗時(shí)猴抹,運(yùn)維人員希望能夠通過(guò)查看日志和查看服務(wù)之間的調(diào)用關(guān)系來(lái)定位問(wèn)題整陌,而Spring cloud sleuth組件正是為了解決微服務(wù)跟蹤的組件划纽。

sleuth的原理介紹可以參考這篇文章: 服務(wù)鏈路追蹤(Spring Cloud Sleuth)

本文主要講解sleuth的兩方面用法

  • sleuth+elk 結(jié)合脆侮,聚合微服務(wù)日志
  • sleuth+ zipkin結(jié)合,顯示文件調(diào)用鏈路

本文代碼參考hello+world+helloworldh+helloworldfeign+track這5個(gè)項(xiàng)目

sleuth+elk聚合日志

sleuth配置

  • 在微服務(wù)項(xiàng)目引入下列依賴(lài)
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
  • 配置文件application.yml增加
logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG

  • 依次啟動(dòng)hello項(xiàng)目helloworld項(xiàng)目勇劣,在瀏覽器輸入http://localhost:8020/message后兩個(gè)項(xiàng)目的控制臺(tái)輸出如下日志
helloworld日志
hello 日志.png

其中a7c81616d25c1a88是TraceId靖避,后面跟著的是SpanId,依次調(diào)用有一個(gè)全局的TraceId比默,將調(diào)用鏈路串起來(lái)幻捏。

查看日志文件并不是一個(gè)很好的方法,當(dāng)微服務(wù)越來(lái)越多日志文件也會(huì)越來(lái)越多退敦,通過(guò)ELK可以將日志聚合粘咖,并進(jìn)行可視化展示和全文檢索蚣抗。

sleuth配合elk使用

ELK是一款日志分析系統(tǒng)侈百,它是Logstash+ElasticSearch+Kibana的技術(shù)組合,它可以通過(guò)logstash收集各個(gè)微服務(wù)日志翰铡,并通過(guò)Kibana進(jìn)行可視化展示钝域,而且還可以對(duì)大量日志信息通過(guò)ElasticSearch進(jìn)行全文檢索。

ELK.png

操作步驟:

區(qū)別是在啟動(dòng)logstash時(shí),指定了日志來(lái)源路徑

/opt/logstash/bin/logstash -e 
'input { file { codec => json path => "/opt/build/*.json" } } 
output { elasticsearch { hosts => ["localhost"] } }'
  • 項(xiàng)目添加依賴(lài)
      <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>4.9</version>
        </dependency>
  • 在src/java/resources目錄下新建logback-spring.xml,配置如下內(nèi)容
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <springProperty scope="context"
                    name="springAppName"
                    source="spring.application.name"/>

    <property name="LOG_FILE"
              value="${BUILD_FOLDER:-build}/${springAppName}"/>

    <property name="CONSOLE_LOG_PATTERN"
              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p})
              %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan}
              %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    <!-- 控制臺(tái)輸出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>


    <!-- 按照每天生成日志文件 -->
    <appender name="filelog"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件輸出的文件名-->
            <FileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</FileNamePattern>
            <!--日志文件保留天數(shù)-->
            <MaxHistory>7</MaxHistory>
        </rollingPolicy>
        <encoder>
            <!--格式化輸出:%d表示日期迷捧,%thread表示線(xiàn)程名织咧,%-5level:級(jí)別從左顯示5個(gè)字符寬度%msg:日志消息胀葱,%n是換行符-->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>


    <!-- 使用json格式保存日志文件 -->
    <appender name="jsonlog"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}.json</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件輸出的文件名-->
            <FileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</FileNamePattern>
            <!--日志文件保留天數(shù)-->
            <MaxHistory>7</MaxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <pattern>
                    <pattern>
                        {
                        "severity": "%level",
                        "service": "${springAppName:-}",
                        "trace": "%X{X-B3-TraceId:-}",
                        "span": "%X{X-B3-SpanId:-}",
                        "parent": "%X{X-B3-ParentSpanId:-}",
                        "exportable": "%X{X-Span-Export:-}",
                        "pid": "${PID:-}",
                        "thread": "%thread",
                        "class": "%logger{40}",
                        "rest": "%message"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="jsonlog"/>
        <appender-ref ref="filelog"/>
    </root>


</configuration>

因?yàn)樯厦娴娜罩疚募玫絪pring.application.name,所以需要項(xiàng)目名稱(chēng)的配置挪到bootstrap.yml笙蒙。

  • 測(cè)試結(jié)果抵屿,在瀏覽器輸入http://localhost:8020/message發(fā)起幾次調(diào)用后,打開(kāi)http://localhost:5601后看到上述的Kibana頁(yè)面捅位,說(shuō)明可以正常使用ELK查詢(xún)轧葛,分析跟蹤日志。

sleuth 結(jié)合zipkin

通過(guò)查看日志分析微服務(wù)的調(diào)用鏈路并不是一個(gè)很直觀(guān)的方案艇搀,結(jié)合zipkin可以很直觀(guān)地顯示微服務(wù)之間的調(diào)用關(guān)系尿扯。

trace列表.png
trace明細(xì).png
服務(wù)依賴(lài)關(guān)系.png

通過(guò)zipkin可以將調(diào)用鏈路可視化顯示。
下面講解配置步驟:

服務(wù)端zipkin-server配置

  • 新建項(xiàng)目track焰雕,并引入依賴(lài)
    <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-server</artifactId>
        </dependency>
        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-autoconfigure-ui</artifactId>
     </dependency>
  • 啟動(dòng)類(lèi)添加@EnableDiscoveryClient@EnableZipkinServer注解
  • 配置文件application.yml
spring:
  application:
    name: sleuth-server
server:
  port: 9411

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
      instanceId: ${spring.application.name}:${spring.cloud.client.ipAddress}:${server.port}

以上服務(wù)端就搭建好了

客戶(hù)端整合zipkin步驟

  • 客戶(hù)端添加依賴(lài)
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>  
  • 配置文件添加
spring:
  zipkin:
    base-url: http://127.0.0.1:9411
  sleuth:
    sampler:
      percentage: 1.0

指定了zipkin server的地址衷笋,下面制定需采樣的百分比,默認(rèn)為0.1淀散,即10%右莱,這里配置1,是記錄全部的sleuth信息档插,是為了收集到更多的數(shù)據(jù)(僅供測(cè)試用)慢蜓。在分布式系統(tǒng)中,過(guò)于頻繁的采樣會(huì)影響系統(tǒng)性能郭膛,所以這里配置需要采用一個(gè)合適的值晨抡。

zipkin改進(jìn)

在這里對(duì)zipkin進(jìn)行改進(jìn),主要包含兩方面

  • 通過(guò)消息中間件收集sleuth數(shù)據(jù)
  • 持久化sleuth數(shù)據(jù)

1则剃、通過(guò)消息中間件收集sleuth數(shù)據(jù)
通過(guò)消息中間件可以將zipkin server和微服務(wù)解耦耘柱,微服務(wù)無(wú)需知道zipkin server地址,只需將sleuth數(shù)據(jù)傳入消息中間件棍现。同時(shí)调煎,也可以解決zipkin server與微服務(wù)網(wǎng)絡(luò)不通情況。

改造服務(wù)端

  • 修改zipkin server(trace項(xiàng)目)配置
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>

    <!--    <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-server</artifactId>
        </dependency>-->
        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-autoconfigure-ui</artifactId>
        </dependency>
  • 配置文件application.yml增加
  rabbitmq:
    host: localhost
    port: 5673
    username: guest
    password: guest

這是sleuth數(shù)據(jù)來(lái)源

  • 啟動(dòng)類(lèi)@EnableZipkinServer改為@EnableZipkinStreamServe
    以上服務(wù)端改造完畢己肮,下面改造客戶(hù)端(以helloworld-feign項(xiàng)目為例

改造客戶(hù)端
helloworldfeign項(xiàng)目為例

  • 修改依賴(lài)
  <!-- 使用消息中間件后士袄,不再直接和zipkin server-->
       <!-- <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>-->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-stream</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>
  • 配置文件增加
spring:
  rabbitmq:
    host: localhost
    port: 5673
    username: guest
    password: guest

并刪除下面指向zipkin server的配置

spring:
  zipkin:
    base-url: http://127.0.0.1:9411

這樣就完成了客戶(hù)端的配置,依次啟動(dòng)trackhelloworldfeign項(xiàng)目谎僻,通過(guò)http://localhost:8030/message調(diào)用其他服務(wù)后娄柳,在zipkin server 成功獲取了helloworldfeign的sleuth數(shù)據(jù)。

在以上的過(guò)程中艘绍,只要重啟zipkin server,發(fā)現(xiàn)之前的數(shù)據(jù)丟失赤拒。這是因?yàn)閦ipkin server獲取的數(shù)據(jù)是放在內(nèi)存的,我們可以獲取的服務(wù)追蹤數(shù)據(jù)放入到ElasticSearch

2、持久化sleuth數(shù)據(jù)

  • 修改依賴(lài)

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
        </dependency>

        <!-- 持久化到ElasticSearch-->
        <!--<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>-->
        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
            <version>1.29.2</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>

           <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-autoconfigure-ui</artifactId>
        </dependency>
  • 配置文件增加
zipkin:
  storage:
    type: elasticsearch
    elasticsearch:
      cluster: elasticsearch
      hosts: http://localhost:9200
      index: zipkin
      index-shards: 5
      index-replicas: 1

再次啟動(dòng)track項(xiàng)目后挎挖,可以將數(shù)據(jù)持久化到elasticsearch这敬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蕉朵,隨后出現(xiàn)的幾起案子鹅颊,更是在濱河造成了極大的恐慌,老刑警劉巖墓造,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堪伍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡觅闽,警方通過(guò)查閱死者的電腦和手機(jī)帝雇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蛉拙,“玉大人尸闸,你說(shuō)我怎么就攤上這事≡谐” “怎么了吮廉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)畸肆。 經(jīng)常有香客問(wèn)我宦芦,道長(zhǎng),這世上最難降的妖魔是什么轴脐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任调卑,我火速辦了婚禮,結(jié)果婚禮上大咱,老公的妹妹穿的比我還像新娘恬涧。我一直安慰自己,他們只是感情好碴巾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布溯捆。 她就那樣靜靜地躺著,像睡著了一般厦瓢。 火紅的嫁衣襯著肌膚如雪提揍。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天旷痕,我揣著相機(jī)與錄音碳锈,去河邊找鬼顽冶。 笑死欺抗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的强重。 我是一名探鬼主播绞呈,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼贸人,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了佃声?” 一聲冷哼從身側(cè)響起艺智,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎圾亏,沒(méi)想到半個(gè)月后十拣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡志鹃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年夭问,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曹铃。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缰趋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出陕见,到底是詐尸還是另有隱情秘血,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布评甜,位于F島的核電站灰粮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忍坷。R本人自食惡果不足惜谋竖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望承匣。 院中可真熱鬧蓖乘,春花似錦、人聲如沸韧骗。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)袍暴。三九已至些侍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間政模,已是汗流浹背岗宣。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淋样,地道東北人耗式。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親刊咳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子彪见,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)娱挨,斷路器余指,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 普元推出DevOps系列課程,5分鐘秒懂一個(gè)知識(shí)點(diǎn)跷坝,戳“閱讀原文”充電5分鐘酵镜,掌握黑科技。 轉(zhuǎn)載本文需注明出處:微...
    72a1f772fe47閱讀 4,509評(píng)論 0 0
  • 從今起柴钻,本座名約白蓮教主笋婿,小名啊白,小白顿颅,全面招收教徒缸濒,現(xiàn)已收貨護(hù)法一枚
    不如懷念9527閱讀 857評(píng)論 0 0
  • 暑假回了一趟外婆家庇配,正值酷暑,那炙熱的陽(yáng)光照到人身上绍些,熱得人快要窒息似的捞慌。 那天下午,外公和舅舅突然說(shuō)要搬柴柬批,我心...
    靈風(fēng)Alex閱讀 335評(píng)論 0 0
  • 前不久我在網(wǎng)上看到一句話(huà): " 愛(ài)情對(duì)生命的意義是帶來(lái)蛻變啸澡,每一段戀情、每一個(gè)戀人氮帐,帶來(lái)關(guān)鍵性的蛻變契機(jī)嗅虏。" 我一...
    L_7b26閱讀 175評(píng)論 0 0