1. 程式人生 > 實用技巧 >微服務的鏈路追蹤

微服務的鏈路追蹤

1 微服務架構下的問題

  • 在大型系統的微服務化構建中,一個系統會被拆分成許多模組。這些模組負責不同的功能,組合成系統,最終可以提供豐富的功能。在這種架構中,一次請求往往需要涉及到多個服務。網際網路應用構建在不同的軟體模組集上,這些軟體模組,可能是由不同團隊開發、可能使用不同的程式語言來實現、可能部署在幾千臺伺服器上,橫跨多個不同的資料中心,也就意味著這種架構形式也會存在一些問題:
    • 1️⃣如何快速的發現問題?
    • 2️⃣如何判斷故障影響範圍?
    • 3️⃣如何梳理服務依賴以及依賴的合理性?
    • 4️⃣如何分析鏈路效能問題以及實時容量規劃?
  • 分散式鏈路追蹤(Distributed Tracing),就是將一次分散式請求還原成呼叫鏈路,進行日誌記錄,效能監控並將一次分散式請求的呼叫情況集中展示。比如各個服務節點上的耗時、請求具體到達那臺機器上、每個服務節點的請求狀態等等。
  • 目前業界比較流行的鏈路追蹤系統如:Twitter的Zipkin,阿里的鷹眼,美團的Mtrace,大眾點評的cat等,大部分都是基於Google發表的Dapper。Dapper闡述了分散式系統,特別是微服務架構中鏈路追蹤的概念、資料展示、埋點、傳遞、收集、儲存和展示等技術細節。

2 Sleuth概述

2.1 簡介

  • Spring Cloud Sleuth主要功能就是在分散式系統中提供追蹤解決方案,並且相容支援了zipkin,只需要在pom檔案中引入相應的依賴即可。

2.2 相關概念

  • Spring Cloud Sleuth為Spring Cloud提供了分散式追蹤解決方案。它大量借用了Google的Dapper的設計。需要先了解一下Sleuth中的術語和相關概念。
  • Spring Cloud Sleuth採用的是Google的開源專案Dapper的專業術語。
  • Span:基本工作單元,例如:在一個新建的span中傳送一個RPC等同於傳送一次迴應請求給RPC,span通過一個64位ID唯一標識,trace以另一個64位ID標識,span還有其他資料資訊,比如摘要、時間戳事件、關鍵值註釋(tags)、span的ID以及進度ID(通常是IP地址),span在不斷的啟動和停止的同時記錄了時間資訊,當你建立了一個span,你必須在未來的某個時刻停止它。
  • Trace:一系列span組成的一個樹狀結構。例如,當你正在跑一個分散式大資料工程,你可能需要建立Trace。
  • Annotation:用來及時記錄一個事件的存在,一些核心annotations用來定義一個請求的開始和結束。
    • cs-Client Server:客戶端傳送一個請求,這個annotation描述了這個span的開始。
    • sr-Server Received:服務端獲得請求並準備開始處理它,如果將其srj減去cs時間戳便可得到網路延遲。
    • ss-Server Sent:註解表明請求處理的完成(當請求返回客戶端),如果ss減去sr時間戳便可得到服務端需要的處理請求時間。
    • cr-Client Received:表明span的結束,客戶端成功接收到服務端的回覆,如果cr減去cs時間戳便可得到客戶端從服務端獲取回覆的所有所需時間。

3 鏈路追蹤Sleuth入門

3.1 在閘道器層、訂單微服務、商品微服務匯入Sleuth的依賴

  • 修改部分:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
  • 閘道器層的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api_gateway_server7007</artifactId>

    <dependencies>
        <!--
            Spring Cloud Gateway使用的web框架是webflux,和SpringMVC不相容。引入的限流元件是Hystrix。Redis底層不再使用jedis,而是lettuce。
        -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
    </dependencies>

</project>
  • 訂單微服務的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order_service8003</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--   匯入Eureka Client對應的座標     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

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

</project>
  • 商品微服務的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product_service9004</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--   匯入Eureka Client對應的座標     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
    </dependencies>

</project>

3.2 修改閘道器層、訂單微服務、商品微服務的配置檔案

  • 修改部分:
logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
  • 閘道器層的完整application.yml:
server:
  port: 7007

spring:
  application:
    name: api-gateway-server
  # 配置 Spring Cloud Gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 開啟從註冊中心動態建立路由的功能,利用微服務名進行路由
          lower-case-service-id: true # 微服務名稱以小寫形式呈現
      routes:
        # 配置路由: 路由id,路由到微服務的uri,斷言(判斷條件)
        - id: product-service    # 路由id
          #          uri: http://localhost:9004
          uri: lb://service-product # 路由到微服務的uri。 lb://xxx,lb代表從註冊中心獲取服務列表,xxx代表需要轉發的微服務的名稱
          predicates:                # 斷言(判斷條件)
            #  - Path=/product/**
            - Path=/product-service/**
          filters: # 配置路由過濾器  http://localhost:7007/product-service/product/findById/1 --> http://localhost:7007/product/findById/1
            - RewritePath=/product-service/(?<segment>.*), /$\{segment} # 路徑重寫的過濾器

# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: api-gateway-server:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/


logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug
  • 訂單微服務的完整application.yml:
server:
  port: 8003 # 微服務的埠號

spring:
  application:
    name: service-order # 微服務的名稱

# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: service-order:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

feign:
  hystrix: # 開啟Feign中的Hystrix
    enabled: true

# 暴露所有端點
management:
  endpoints:
    web:
      exposure:
        include: '*'

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 # 預設的連線超時時間為1秒,如果1秒沒有返回資料,就自動觸發降級邏輯

# 微服務info內容詳細資訊
info:
  app.name: xxx
  company.name: xxx
  build.artifactId: $project.artifactId$
  build.version: $project.version$

logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug
  • 商品微服務的完整application.yml:
server:
  port: 9004 # 微服務的埠號

spring:
  application:
    name: service-product # 微服務的名稱
  datasource:
    url: jdbc:mysql://192.168.217.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
  jpa:
    generate-ddl: true
    show-sql: true
    open-in-view: true
    database: mysql

# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: service-product:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug


# 微服務info內容詳細資訊
info:
  app.name: xxx
  company.name: xxx
  build.artifactId: $project.artifactId$
  build.version: $project.version$

3.3 重啟閘道器層、訂單微服務、商品微服務

  • 重啟之後,我們可以在控制檯觀察到Sleuth的日誌輸出。

  • 其中,81a807d076c2a9f6是TraceId,後面跟著的是SpanId,依次呼叫有一個全域性的TranceId,將呼叫鏈路串起來。仔細分析每個微服務的日誌,不難看出請求的具體過程。
  • 檢視日誌檔案並不是一個很好的方法,當微服務越來越多日誌檔案也會越來越多,通過ZipKin可以將日誌聚合,並進行視覺化展示和全文檢索。

4 ZipKin概述

  • Zipkin是Twitter的一個開源專案,它基於Google Dapper實現,它致力於收集服務的定時資料,以解決微服務架構中的延遲問題,包括資料的收集、儲存、查詢和展現。我們可以使用它來收集各個伺服器上請求鏈路的跟蹤資料,並通過它提供的REST API介面來輔助我們查詢跟蹤以實現分散式系統的監控程式,從而及時的發現系統中出現的延遲升高的問題並找出系統性能瓶頸的根源。除了面向開發的API介面之外,它也提供了方便的UI元件來幫助我們直觀的搜尋跟蹤資訊和分析請求鏈路明細,比如:可以查詢某段時間內各使用者請求的處理時間等。Zipkin提供了可插拔資料儲存方式:In-Memory、MySQL、Cassandra以及ElasticSearch。

  • 上圖展示了Zipkin的基礎架構,它主要由4個核心元件構成:
    • Collector:收集器元件,它主要用於處理從外部系統傳送過來的跟蹤資訊,將這些資訊轉換為Zipkin內部處理的span格式,以支援後續的儲存、分析、展示等功能。
    • Storage:儲存元件,它主要對處理收集器接收到的跟蹤資訊,預設會將這些資訊儲存在記憶體中,我們也可以修改此儲存策略,將跟蹤資訊儲存到資料庫中。
    • Restful API:API元件,它主要用來提供外部訪問介面。比如給客戶端展示跟蹤資訊,或者外接系統訪問以實現監控等。
    • Web UI:UI元件,基於API元件實現的上層應用。通過UI元件使用者可以方便而直觀的查詢和分析跟蹤資訊。
  • Zipkin分為兩端,一個是Zipkin服務端,一個是Zipkin客戶端,客戶端也就是微服務的應用。客戶端會配置服務端的URL地址,一旦發生服務間的呼叫時候,會被配置在微服務裡面的Sleuth的監聽器監聽,並生成相應的Trace和Span資訊傳送給服務端。
  • 傳送的方式有兩種:一種是HTTP報文的方式,另外一種是訊息匯流排的方式如RabbitMQ。
  • 不論哪種方式,我們都需要:
    • 一個Eureka服務註冊中心。
    • 一個Zipkin服務端。
    • 多個微服務,這些微服務中配置了Zipkin客戶端。

5 Zipkin Server的部署和配置

2.1 Zipkin Server下載

  • 從SpringBoot2.0開始,官方就不再支援使用自建Zipkin Server的方式進行服務鏈路追蹤,而是直接提供了編譯好的jar包來給我們使用。可以從官方網站上下載Zipkin的Web UI

2.2 啟動

  • 在命令列輸入java -jar zipkin-server-2.12.9-exec.jar啟動Zipkin Server。

  • 預設Zipkin Server的請求埠是9411.
  • 在瀏覽器輸入http://localhost:9411即可進入到Zipkin Server的管理後臺。

2.3 使用Docker啟動Zipkin Server

docker run -d -p 9411:9411 --name zipkin  openzipkin/zipkin:2.12.9

6 客戶端Zipkin和Sleuth整合

6.1 概述

  • 通過檢視日誌分析微服務的呼叫鏈路並不是一個很直觀的方案,結合Zipkin可以很直觀的顯示微服務之間的呼叫關係。

6.2 客戶端Zipkin和Sleuth整合

6.2.1 閘道器層、訂單微服務和商品微服務新增Zipkin的依賴

  • 修改部分:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
  • 閘道器層的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api_gateway_server7007</artifactId>

    <dependencies>
        <!--
            Spring Cloud Gateway使用的web框架是webflux,和SpringMVC不相容。引入的限流元件是Hystrix。Redis底層不再使用jedis,而是lettuce。
        -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
    </dependencies>

</project>
  • 訂單微服務的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order_service8003</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--   匯入Eureka Client對應的座標     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

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

</project>
  • 商品微服務的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product_service9004</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--   匯入Eureka Client對應的座標     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
    </dependencies>

</project>

6.2.2 閘道器層、訂單微服務和商品微服務修改配置檔案

  • 修改部分:
spring:  
  # zipkin
  zipkin:
    base-url: http://192.168.217.100:9411/ # Zipkin Server端的請求地址
    sender:
      type: web # 資料的傳輸方式,以HTTP的形式向Zipkin Server端傳送資料
  sleuth:
    sampler:
      probability: 1 # 取樣比  預設為0.1,即10%,這裡配置1,是記錄全部的sleuth資訊,是為了收集到更多的資料(僅供測試使用)
  • 閘道器層完整的application.yml:
server:
  port: 7007

spring:
  application:
    name: api-gateway-server
  # 配置 Spring Cloud Gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 開啟從註冊中心動態建立路由的功能,利用微服務名進行路由
          lower-case-service-id: true # 微服務名稱以小寫形式呈現
      routes:
        # 配置路由: 路由id,路由到微服務的uri,斷言(判斷條件)
        - id: product-service    # 路由id
          #          uri: http://localhost:9004
          uri: lb://service-product # 路由到微服務的uri。 lb://xxx,lb代表從註冊中心獲取服務列表,xxx代表需要轉發的微服務的名稱
          predicates:                # 斷言(判斷條件)
            #  - Path=/product/**
            - Path=/product-service/**
          filters: # 配置路由過濾器  http://localhost:7007/product-service/product/findById/1 --> http://localhost:7007/product/findById/1
            - RewritePath=/product-service/(?<segment>.*), /$\{segment} # 路徑重寫的過濾器
  # zipkin
  zipkin:
    base-url: http://192.168.217.100:9411/ # Zipkin Server端的請求地址
    sender:
      type: web # 資料的傳輸方式,以HTTP的形式向Zipkin Server端傳送資料
  sleuth:
    sampler:
      probability: 1 # 取樣比  預設為0.1,即10%,這裡配置1,是記錄全部的sleuth資訊,是為了收集到更多的資料(僅供測試使用)

# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: api-gateway-server:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/




logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug
  • 訂單微服務完整的application.yml:
server:
  port: 8003 # 微服務的埠號

spring:
  application:
    name: service-order # 微服務的名稱
  # zipkin
  zipkin:
    base-url: http://192.168.217.100:9411/ # Zipkin Server端的請求地址
    sender:
      type: web # 資料的傳輸方式,以HTTP的形式向Zipkin Server端傳送資料
  sleuth:
    sampler:
      probability: 1 # 取樣比  預設為0.1,即10%,這裡配置1,是記錄全部的sleuth資訊,是為了收集到更多的資料(僅供測試使用)
# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: service-order:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

feign:
  hystrix: # 開啟Feign中的Hystrix
    enabled: true

# 暴露所有端點
management:
  endpoints:
    web:
      exposure:
        include: '*'

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 # 預設的連線超時時間為1秒,如果1秒沒有返回資料,就自動觸發降級邏輯

# 微服務info內容詳細資訊
info:
  app.name: xxx
  company.name: xxx
  build.artifactId: $project.artifactId$
  build.version: $project.version$

logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug
  • 商品微服務完整的application.yml:
server:
  port: 9004 # 微服務的埠號

spring:
  application:
    name: service-product # 微服務的名稱
  datasource:
    url: jdbc:mysql://192.168.217.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
  jpa:
    generate-ddl: true
    show-sql: true
    open-in-view: true
    database: mysql
  # zipkin
  zipkin:
    base-url: http://192.168.217.100:9411/ # Zipkin Server端的請求地址
    sender:
      type: web # 資料的傳輸方式,以HTTP的形式向Zipkin Server端傳送資料
  sleuth:
    sampler:
      probability: 1 # 取樣比  預設為0.1,即10%,這裡配置1,是記錄全部的sleuth資訊,是為了收集到更多的資料(僅供測試使用)
# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: service-product:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug


# 微服務info內容詳細資訊
info:
  app.name: xxx
  company.name: xxx
  build.artifactId: $project.artifactId$
  build.version: $project.version$

6.2.3 測試

  • 分別重啟閘道器層、訂單微服務和商品微服務,通過瀏覽器傳送一次微服務請求。開啟Zipkin的Web UI控制檯,我們可以根據條件追蹤每次請求呼叫過程。

  • 點選該trace可以看到請求的細節:

7 分析Zipkin整合Sleuth的問題

  • 由上圖可知:
  • 1️⃣鏈路資料如何持久化儲存(當前資料儲存在Zipkin服務端的記憶體中,斷電易丟失)。
  • 2️⃣如何優化資料採集過程(HTTP方式是同步阻塞方式,一旦出現網路波動等情況,可能會波及業務系統)。

8 儲存跟蹤資料

8.1 概述

  • Zipkin Server預設是將追蹤資料資訊儲存到記憶體中,這種方式不適合生產環境。因為一旦Zipkin Server端關閉重啟或者服務崩潰,就會導致歷史資料小時。Zipkin支援將追蹤資料持久化到MySQL資料庫中或者儲存到ElasticSearch中。

8.2 準備資料庫

  • 可以從官網中找到Zipkin Server持久化的MySQL資料庫指令碼:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for zipkin_annotations
-- ----------------------------
DROP TABLE IF EXISTS `zipkin_annotations`;
CREATE TABLE `zipkin_annotations`  (
  `trace_id_high` bigint(20) NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` bigint(20) NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
  `span_id` bigint(20) NOT NULL COMMENT 'coincides with zipkin_spans.id',
  `a_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
  `a_value` blob NULL COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
  `a_type` int(11) NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
  `a_timestamp` bigint(20) NULL DEFAULT NULL COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
  `endpoint_ipv4` int(11) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_ipv6` binary(16) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
  `endpoint_port` smallint(6) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_service_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
  UNIQUE INDEX `trace_id_high`(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) USING BTREE COMMENT 'Ignore insert on duplicate',
  INDEX `trace_id_high_2`(`trace_id_high`, `trace_id`, `span_id`) USING BTREE COMMENT 'for joining with zipkin_spans',
  INDEX `trace_id_high_3`(`trace_id_high`, `trace_id`) USING BTREE COMMENT 'for getTraces/ByIds',
  INDEX `endpoint_service_name`(`endpoint_service_name`) USING BTREE COMMENT 'for getTraces and getServiceNames',
  INDEX `a_type`(`a_type`) USING BTREE COMMENT 'for getTraces and autocomplete values',
  INDEX `a_key`(`a_key`) USING BTREE COMMENT 'for getTraces and autocomplete values',
  INDEX `trace_id`(`trace_id`, `span_id`, `a_key`) USING BTREE COMMENT 'for dependencies job'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compressed;

-- ----------------------------
-- Table structure for zipkin_dependencies
-- ----------------------------
DROP TABLE IF EXISTS `zipkin_dependencies`;
CREATE TABLE `zipkin_dependencies`  (
  `day` date NOT NULL,
  `parent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `child` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `call_count` bigint(20) NULL DEFAULT NULL,
  `error_count` bigint(20) NULL DEFAULT NULL,
  PRIMARY KEY (`day`, `parent`, `child`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compressed;

-- ----------------------------
-- Table structure for zipkin_spans
-- ----------------------------
DROP TABLE IF EXISTS `zipkin_spans`;
CREATE TABLE `zipkin_spans`  (
  `trace_id_high` bigint(20) NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` bigint(20) NOT NULL,
  `id` bigint(20) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `remote_service_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `parent_id` bigint(20) NULL DEFAULT NULL,
  `debug` bit(1) NULL DEFAULT NULL,
  `start_ts` bigint(20) NULL DEFAULT NULL COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
  `duration` bigint(20) NULL DEFAULT NULL COMMENT 'Span.duration(): micros used for minDuration and maxDuration query',
  PRIMARY KEY (`trace_id_high`, `trace_id`, `id`) USING BTREE,
  INDEX `trace_id_high`(`trace_id_high`, `trace_id`) USING BTREE COMMENT 'for getTracesByIds',
  INDEX `name`(`name`) USING BTREE COMMENT 'for getTraces and getSpanNames',
  INDEX `remote_service_name`(`remote_service_name`) USING BTREE COMMENT 'for getTraces and getRemoteServiceNames',
  INDEX `start_ts`(`start_ts`) USING BTREE COMMENT 'for getTraces ordering and range'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compressed;

SET FOREIGN_KEY_CHECKS = 1;

8.3 命令列方式配置啟動服務端

# STORAGE_TYPE 儲存型別    
# MYSQL_HOST MySQL主機地址
# MYSQL_TCP_PORT MySQL埠
# MYSQL_DB MySQL資料庫名稱
# MYSQL_USER MySQL使用者名稱
# MYSQL_PASS MySQL地址
java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=192.168.217.100 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=123456

8.3 Docker方式配置啟動服務端

docker run -d \
-p 9411:9411 \
--restart always \
-v /etc/localtime:/etc/localtime:ro \
-e MYSQL_USER=root \
-e MYSQL_PASS=123456 \
-e MYSQL_HOST=192.168.217.100 \
-e STORAGE_TYPE=mysql \
-e MYSQL_DB=zipkin \
-e MYSQL_TCP_PORT=3306 \
--name zipkin \
openzipkin/zipkin:2.12.9

8.4 測試

  • 配置好服務daunt之後,可以在瀏覽器中請求幾次。回到資料庫檢視,會發現資料已經持久化到MySQL中了。

9 基於訊息中介軟體收集資料

9.1 概述

  • 在預設情況下,Zipkin客戶端和Zipkin服務端之間是使用HTTP請求的方式進行通訊(即同步的請求方式)。
  • 在網路波動,Zipkin服務端異常等情況下,可能會存在資訊收集不機制的問題。
  • Zipkin支援和RabbitMQ整合完整非同步訊息傳輸。

9.2 步驟

  • 1️⃣準備RabbitMQ中介軟體。
  • 2️⃣修改Zipkin客戶端,將訊息傳送到MQ伺服器。
  • 3️⃣修改Zipkin服務daunt,從MQ中拉取訊息。

9.3 RabbitMQ的安裝和啟動

  • 以Docker形式安裝和啟動RabbitMQ:
docker run -d  --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq:management

9.4 命令列方式配置啟動服務端

# STORAGE_TYPE 儲存型別    
# MYSQL_HOST MySQL主機地址
# MYSQL_TCP_PORT MySQL埠
# MYSQL_DB MySQL資料庫名稱
# MYSQL_USER MySQL使用者名稱
# MYSQL_PASS MySQL地址
# RABBIT_ADDRESSES 指定Rabbitmq的地址
# RABBIT_USER 使用者名稱(預設為guest)
# RABBIT_PASSWORD 密碼(預設為guest)
java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=192.168.217.100 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=123456 --RABBIT_ADDRESSES=192.168.217.100:5672 --RABBIT_USER=guest --RABBIT_PASSWORD=guest

9.5 Docker方式啟動配置啟動服務端

docker run -d \
-p 9411:9411 \
--restart always \
-v /etc/localtime:/etc/localtime:ro \
-e MYSQL_USER=root \
-e MYSQL_PASS=123456 \
-e MYSQL_HOST=192.168.217.100 \
-e STORAGE_TYPE=mysql \
-e MYSQL_DB=zipkin \
-e MYSQL_TCP_PORT=3306 \
-e RABBIT_ADDRESSES=192.168.217.100:5672 \
-e RABBIT_USER=guest \
-e RABBIT_PASSWORD=guest \
--name zipkin \
openzipkin/zipkin:2.12.9

9.6 客戶端配置

9.6.1 匯入相關jar包的Maven座標

  • 修改部分:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  • 閘道器層的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api_gateway_server7007</artifactId>

    <dependencies>
        <!--
            Spring Cloud Gateway使用的web框架是webflux,和SpringMVC不相容。引入的限流元件是Hystrix。Redis底層不再使用jedis,而是lettuce。
        -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

    </dependencies>

</project>
  • 訂單微服務的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order_service8003</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--   匯入Eureka Client對應的座標     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
    </dependencies>

</project>
  • 商品微服務的完整pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product_service9004</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--   匯入Eureka Client對應的座標     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
    </dependencies>

</project>

9.6.2 配置訊息中介軟體的地址

  • 修改部分:
spring:
  # zipkin
  zipkin:
    #    base-url: http://192.168.217.100:9411/ # Zipkin Server端的請求地址
    sender:
      type: rabbit
  #      type: web # 資料的傳輸方式,以HTTP的形式向Zipkin Server端傳送資料
  sleuth:
    sampler:
      probability: 1 # 取樣比  預設為0.1,即10%,這裡配置1,是記錄全部的sleuth資訊,是為了收集到更多的資料(僅供測試使用)
  rabbitmq:
    host: 192.168.217.100
    port: 5672
    username: guest
    password: guest
    # 重試機制
    listener:
      direct:
        retry:
          enabled: true
      simple:
        retry:
          enabled: true
  • 閘道器層的完整application.yml
server:
  port: 7007

spring:
  application:
    name: api-gateway-server
  # 配置 Spring Cloud Gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 開啟從註冊中心動態建立路由的功能,利用微服務名進行路由
          lower-case-service-id: true # 微服務名稱以小寫形式呈現
      routes:
        # 配置路由: 路由id,路由到微服務的uri,斷言(判斷條件)
        - id: product-service    # 路由id
          #          uri: http://localhost:9004
          uri: lb://service-product # 路由到微服務的uri。 lb://xxx,lb代表從註冊中心獲取服務列表,xxx代表需要轉發的微服務的名稱
          predicates:                # 斷言(判斷條件)
            #  - Path=/product/**
            - Path=/product-service/**
          filters: # 配置路由過濾器  http://localhost:7007/product-service/product/findById/1 --> http://localhost:7007/product/findById/1
            - RewritePath=/product-service/(?<segment>.*), /$\{segment} # 路徑重寫的過濾器
  # zipkin
  zipkin:
    #    base-url: http://192.168.217.100:9411/ # Zipkin Server端的請求地址
    sender:
      type: rabbit
  #      type: web # 資料的傳輸方式,以HTTP的形式向Zipkin Server端傳送資料
  sleuth:
    sampler:
      probability: 1 # 取樣比  預設為0.1,即10%,這裡配置1,是記錄全部的sleuth資訊,是為了收集到更多的資料(僅供測試使用)
  rabbitmq:
    host: 192.168.217.100
    port: 5672
    username: guest
    password: guest
    # 重試機制
    listener:
      direct:
        retry:
          enabled: true
      simple:
        retry:
          enabled: true

# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: api-gateway-server:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/




logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug
  • 訂單微服務的application.yml
server:
  port: 8003 # 微服務的埠號

spring:
  application:
    name: service-order # 微服務的名稱
  # zipkin
  zipkin:
    #    base-url: http://192.168.217.100:9411/ # Zipkin Server端的請求地址
    sender:
      type: rabbit
  #      type: web # 資料的傳輸方式,以HTTP的形式向Zipkin Server端傳送資料
  sleuth:
    sampler:
      probability: 1 # 取樣比  預設為0.1,即10%,這裡配置1,是記錄全部的sleuth資訊,是為了收集到更多的資料(僅供測試使用)
  rabbitmq:
    host: 192.168.217.100
    port: 5672
    username: guest
    password: guest
    # 重試機制
    listener:
      direct:
        retry:
          enabled: true
      simple:
        retry:
          enabled: true
# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: service-order:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

feign:
  hystrix: # 開啟Feign中的Hystrix
    enabled: true

# 暴露所有端點
management:
  endpoints:
    web:
      exposure:
        include: '*'

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 # 預設的連線超時時間為1秒,如果1秒沒有返回資料,就自動觸發降級邏輯

# 微服務info內容詳細資訊
info:
  app.name: xxx
  company.name: xxx
  build.artifactId: $project.artifactId$
  build.version: $project.version$

logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug
  • 商品微服務的完整application.yml
server:
  port: 9004 # 微服務的埠號

spring:
  application:
    name: service-product # 微服務的名稱
  datasource:
    url: jdbc:mysql://192.168.217.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
  jpa:
    generate-ddl: true
    show-sql: true
    open-in-view: true
    database: mysql
  # zipkin
  zipkin:
    #    base-url: http://192.168.217.100:9411/ # Zipkin Server端的請求地址
    sender:
      type: rabbit
  #      type: web # 資料的傳輸方式,以HTTP的形式向Zipkin Server端傳送資料
  sleuth:
    sampler:
      probability: 1 # 取樣比  預設為0.1,即10%,這裡配置1,是記錄全部的sleuth資訊,是為了收集到更多的資料(僅供測試使用)
  rabbitmq:
    host: 192.168.217.100
    port: 5672
    username: guest
    password: guest
    # 重試機制
    listener:
      direct:
        retry:
          enabled: true
      simple:
        retry:
          enabled: true
# 配置 eureka
eureka:
  instance:
    # 主機名稱:服務名稱修改,其實就是向eureka server中註冊的例項id
    instance-id: service-product:${server.port}
    # 顯示IP資訊
    prefer-ip-address: true
  client:
    service-url: # 此處修改為 Eureka Server的叢集地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug


# 微服務info內容詳細資訊
info:
  app.name: xxx
  company.name: xxx
  build.artifactId: $project.artifactId$
  build.version: $project.version$

9.7 測試

  • 關閉Zipkin Server,並隨意傳送請求。開啟RabbitMQ管理後臺可以看到,消費已經推送到了RabbitMQ中。
  • 當Zipkin Server啟動時,會自動從RabbitMQ獲取訊息並消費,展示追蹤資料。