Spring Cloud Sleuth--服務鏈路追蹤(一)

爲什麼需要Spring Cloud Sleuth

Spring Cloud Seleuth是SpringCloud的一個組件,它的主要功能是在分佈式系統中提供服務鏈路追蹤解決方案。

微服務架構是一個分佈式架構,微服務系統按業務劃分服務單元,一個微服務系統往往有很多個服務單元。由於服務單元數量衆多,業務的複雜性較高,如果出現了錯誤和異常,很難去定位。主要體現在一個請求可能需要調用很多個服務,而內部服務的調用複雜性決定了問題難以定位。所以在微服務架構中,必須實現分佈式鏈路追蹤,去跟進一個請求到底有哪些服務參與,參與的順序又是怎樣的,從而達到每個請求的步驟清晰可見,出了問題能夠快速定位的目的。

Google開源了Dapper 鏈路追蹤組件,並在2010 年發表了論文《Dapper, a Large-ScaleDistributed Systems Tracing Infrastructure)》,這篇論文是業內實現鏈路追蹤的標杆和理論基礎,具有很高的參考價值。

目前,常見的鏈路追蹤組件有Google 的Dapper、Twitter 的Zipkin,以及阿里的Eagleeye(鷹眼)等,它們都是非常優秀的鏈路追蹤開源組件。

基本術語

Spring Cloud Sleuth採用了Google的開源項目Dapper的專業術語。

  1. Span:基本工作單元,發送一個遠程調度任務就會產生一個Span,Span是用一個64位ID唯一標識的,Trace是用另一個64位ID唯一標識的。Span還包含了其他的信息,例如摘要、時間戳事件、Span的ID以及進行ID。
  2. Trace:由一系列Span組成的,呈樹狀結構。請求一個微服務系統的API接口,這個API接口需要調用多個微服務單元,調用每個微服務單元都會產生一個新的Span,所有由這個請求產生的Span組成了這個Trace。
  3. Annotation:用於記錄一個事件,一些核心註解用於定義一個請求的開始和結束:
    • cs-Client Sent:客戶端發送一個請求,這個註解描述了Span的開始;
    • sr-Server Received:服務端獲得請求並準備開始處理它,如果將其sr減去cs時間戳,便可得到網絡傳輸的時間;
    • ss-Server Sent:服務端發送響應,該註解表明請求處理的完成(當請求返回客戶端),用ss的時間戳減去sr時間戳,便可以得到服務器請求的時間。
    • cr-Client Received:客戶端接收響應,此時Span結束,如果cr的時間戳減去cs時間戳,便可以得到請求所消耗的時間;

簡單實例

構建Eureka Server

依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

配置:

server:
  port: 8761

spring:
  application:
    name: eureka-server

eureka:
  client:
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://localhost:${server.port}/eureka/

啓動類:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

構建Zipkin Server:
新建一個Module工程,取名爲zipkin-server, 工程的pom文件繼承了主Maven工程的pom文件,並引入Eureka 的起步依賴spring-cloud-starter-eureka、Zipkin Server 的依賴zipkin-server,以及Zipkin Server 的UI界面依賴zipkin-autoconfigure-ui。後兩個依賴提供了Zipkin的功能和Zipkin界面展示的功能,代碼如下:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</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>
</dependencies>

在程序的啓動類ZipkinServiceApplication加上@EnableZipkinServer註解,開啓ZipkinServer 的功能,加上@EnableEurekaClient註解,啓動Eureka Client,代碼如下:

@SpringBootApplication
@EnableEurekaClient
@EnableZipkinServer
public class ZipkinServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZipkinServerApplication.class, args);
    }
}

配置:

server:
  port: 9411

spring:
  application:
    name: zipkin-server

eureka:
  client:
    service-url: 
      defaultZone: http://localhost:8761/eureka/

構建User Service:
在主Maven工程下建一個Module工程,取名爲user-service,作爲服務提供者,對外暴露API接口。

user-service 工程的pom文件繼承了主Maven工程的pom文件,並引入了Eureka的起步依賴spring-cloud-starter-eureka、Web起步依賴spring-boot- starter-web,以及Zipkin的起步起來spring-cloud-starter-zipkin。

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zipkin</artifactId>
        <version>RELEASE</version>
    </dependency>
</dependencies>

在程序的配置文件applicatiom.yml中,指定程序名爲user-service, 端口號爲8762,服務註冊地址http://localhost:8761/eurea/,Zipkin Server地址爲http://localhost:9411spring.sleuth.sampler.percentage爲1.0, 即以100%的概率將鏈路的數據上傳給Zipkin Server, 在默認情況下,該值爲0.1。配置文件代碼如下:

server:
  port: 8762

spring:
  application:
    name: user-service
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      percentage: 1.0
eureka:
  client:
    service-url: 
      defaultZone: http://localhost:8761/eureka/

在UserController類建一個"/user/hi"的API接口,對外提供服務:

@RestController
@RequestMapping("/user")
public class UserController {
    
    @GetMapping("/hi")
    public String hi() {
        return "I'm forezp";
    }
}

最後作爲Eureka Client,需要在程序的啓動類UserServiceApplication 加上@EnableEurekaClient註解,開啓Eureka Client的功能。

構建Gateway Service:
新建一個名爲gateway-service的工程,這個工程作爲服務網關,將請求轉發到user-service。作爲Zipkin客戶端,需要將鏈路數據上傳給Zipkin Server,同時它也作爲Eureka Client。在工程的pom文件中除了需要繼承主Maven工程的pom文件,還需引入如下的依賴,代碼清單如下:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zuul</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zipkin</artifactId>
        <version>RELEASE</version>
    </dependency>
</dependencies>

在工程的配置文件application.yml中,配置程序名爲gateway-service, 端口號爲5000,服務註冊地址爲http://locahost:8761/eureka/, Zipkin Server 地址爲http://localhost:9411, 以“/user-api/**" 開頭的Uri請求轉發到服務名爲user-service 的服務,配置代碼如下:

server:
  port: 5000

spring:
  application:
    name: gateway-service
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      percentage: 1.0

zuul:
  routes: 
    api-a:
      path: /user-api/**
      serviceId: user-service

在程序的啓動類GatewayServiceApplication 上加@EnableEurekaClient 註解,開啓EurekaClient的功能,加上@EnableZuulProxy註解,開啓Zuul代理功能,代碼如下:

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class GatewayServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayServiceApplication.class, args);
    }
}

測試:
完整的項目搭建完畢,依次啓動eureka-server.zipkin-serveruser service和gateway-service。在瀏覽器上訪問http:/localhost:5000/user-api/user/hi,瀏覽器顯示如下:
在這裏插入圖片描述
訪問http://localhost:9411,即訪問Zipkin的展示界面:
在這裏插入圖片描述
這個界面用於展示Zipkin Server收集的鏈路數據,可以根據服務名、開始時間、結束時間、請求消耗的時間等條件來查找。單擊"Find Tracks"按鈕,從圖中可知請求的調用情況,例如請求的調用時間、消耗時間,以及請求調用的鏈路情況:
在這裏插入圖片描述

單擊“Dependences"按鈕,可以查看服務的依賴關係。在本案例中,gateway-service將請求轉發到了user-service, 這兩個服務的依賴關係如圖:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章