1 前言
在分佈式系統中,往往有着許多服務,又由於請求可能會調用很多個服務以及業務的複雜性,在出現了錯誤之後,我們可能很難去定位。因此,在微服務架構中,我們需要實現分佈式鏈路監控,去跟進一個請求有哪些服務參與以及它們的調用順序,從而令每個請求的步驟清晰,在出現問題時可以實現快速定位。
目前鏈路追蹤組件有 Google 的 Dapper,Twitter 的 Zipkin,阿里的 Eagleeye 等,本文將介紹在 Spring Cloud Sleuth 中如何集成 Zipkin。
2 什麼是 Spring Cloud Sleuth
Spring Cloud Sleuth 實現了一種分佈式的服務鏈路跟蹤解決方案,通過使用 Sleuth 可以讓我們快速定位某個服務的問題。
3 術語介紹
3.1 Span
基本工作單元,每當我們發送一個遠程調度任務就會產生一個 Span,Span 包含一個64位唯一標識的 ID ,一個64位的 Trace ,以及其他數據信息,比如摘要、時間戳事件、Span 處理者的 ID、以及進度 ID。
3.2 Trace
Trace 是一系列 Span 組成的一個樹狀結構。調用每個微服務都會產生一個新的 Span,當我們請求一個微服務系統的 API 接口時可能會調用多個微服務,由這個請求產生的 Span 組成了一個 Trace。
3.3 Annotation
用於及時記錄存在的事件。
- cs (client send) :客戶端發起一個請求,表示 span 開始
- sr (server received):服務器接收到客戶端的請求並開始處理,網絡延遲 = sr - cs
- ss(server send):服務器處理完請求準備返回數據給客戶端,服務器端處理請求花費的時間 = ss - sr
- cr(client received):客戶端接收到處理結果,表示 span 結束,客戶端接收服務端數據的時間 = cr - cs,整個請求所消耗的時間 = cr - cs
4 代碼實戰
4.1 服務鏈路追蹤服務端
我們先構建一個服務鏈路追蹤服務端。新建一個項目,命名爲 zipkin,其 pom.xml 如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>Zipkin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Zipkin</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- zipkin 界面-->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>2.11.5</version>
</dependency>
<!-- zipkin 服務端-->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.11.5</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件
spring.application.name=zipkin
server.port=9411
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
management.metrics.web.server.auto-time-requests=false
spring.main.allow-bean-definition-overriding=true
啓動類上需要添加註解 @EnableZipkinServer
package com.example.Zipkin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import zipkin2.server.internal.EnableZipkinServer;
@SpringBootApplication
@EnableEurekaClient
@EnableZipkinServer
public class ZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinApplication.class, args);
}
}
4.2 服務鏈路追蹤客戶端
我們修改服務提供者 EurekaProducer 項目,將其改造成服務鏈路追蹤客戶端,增加一個依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
配置文件修改如下
spring.application.name=producer
server.port=8080
# zipkin的地址
spring.zipkin.base-url=http://localhost:9411
# 設置採樣率,爲了測試設置100%採集,設置爲1.0
spring.sleuth.sampler.probability=1.0
# 設置與Eureka Server交互的地址,查詢服務和註冊服務都需要依賴這個地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
我們接下來修改一下服務消費者 EurekaConsumer 項目,增加如下依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
配置文件修改如下
spring.application.name=consumer
server.port=8082
# zipkin的地址
spring.zipkin.base-url=http://localhost:9411
# 設置採樣率,爲了測試設置100%採集,設置爲1.0
spring.sleuth.sampler.probability=1.0
# 設置與Eureka Server交互的地址,查詢服務和註冊服務都需要依賴這個地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
5 zipkin 的圖形化數據解析
我們先通過服務消費者遠程調用服務提供者幾次,然後打開 http://localhost:9411/zipkin/
我們可以看到跟蹤信息,每一個框代表一個 Trace
我們點開一個 Trace,可以看到多個 Span
點開每個 Span,可以看到詳細信息