Spring Cloud實戰系列(七) - 服務鏈路追蹤Spring Cloud Sleuth
Spring Cloud Sleuth
的主要功能就是為 分散式系統 提供 追蹤解決方案 ,並且相容支援了 Zipkin
,只需要在 pom.xml
檔案中引入相應的 依賴 即可。本文主要講述 服務追蹤元件 Zipkin
, Spring Cloud Sleuth
集成了 Zipkin
元件。它主要用於 聚集 來自各個 異構系統 的 實時監控資料 ,用來追蹤 微服務架構 下的 系統延時問題 。
正文
1. 相關術語
1.1. Span
Span
是一個基本的 工作單元 ,用於描述一次 RPC
呼叫, Span
通過一個 64
位的 spanId
作為 唯一標識 。 Zipkin
中的 Span
還有其他資料資訊,比如 摘要 、 時間戳事件 、 關鍵值註釋 ( tags
) 以及 進度 ID
(通常是 IP
地址)。 Span
在不斷的啟動和停止,同時記錄了 時間資訊 ,一個 Span
建立後,必須在未來的某個時刻停止它。
1.2. Trace
一系列 Span
組成的一個 樹狀結構 。例如,如果你正在跑一個大型 分散式系統 ,可能需要建立一個 Trace
。
1.3. Annotation
表示 基本標註列表 ,一個 Annotation
可以理解成 Span
生命週期中 重要時刻 的 資料快照 ,比如一個 Annotation
中一般包含 發生時刻 ( timestamp
)、 事件型別 ( value
)、 端點 ( endpoint
)等資訊。其中 Annotation
的 事件型別 包含以下四類:
- cs - Client Sent
客戶端發起一個請求,這個 Annotion
描述了這個 Span
的開始。
- sr - Server Received
服務端獲得請求並 準備開始 處理它,如果將 sr
減去 cs
的 時間戳 便可得到 網路延遲 。
- ss - Server Sent
服務端完成請求處理,如果將 ss
減去 sr
的 時間戳 ,便可得到 服務端 處理請求消耗的時間。
- cr - Client Received
客戶端成功接收到 服務端 的響應,如果將 cr
減去 cs
的 時間戳 ,便可得到 整個請求 所消耗的 總時間 。
2. 專案結構
本文案例主要由 四個模組 組成:
-
eureka-server:作為 服務註冊中心 。
-
zipkin-server:作為 鏈路追蹤服務中心 ,負責儲存 鏈路資料 。
-
service-hi:對外暴露一個 測試介面 ,同時作為 鏈路追蹤 的 服務端 ,負責 產生鏈路資料 。
-
service-zuul:作為 路由閘道器 ,負責 請求轉發 ,同時作為 鏈路追蹤 的 客戶端 ,產生 鏈路資料 ,並上傳至
zipkin-server
。
在 8761
埠 開啟 eureka-server
服務註冊中心 ,參考前面的文章即可,這裡不再演示建立。
3. 構建zipkin-server
新建一個 Spring Boot
應用模組 zipkin-server
,它的 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 http://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>1.5.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>io.github.ostenant.springcloud</groupId> <artifactId>zipkin-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>zipkin-server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Dalston.RELEASE</spring-cloud.version> </properties> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 複製程式碼
在應用的入口類上, 加上註解 @EnableZipkinServer
,開啟 Zipkin Server
的功能。
@EnableZipkinServer @EnableEurekaClient @SpringBootApplication public class ZipkinServerApplication { public static void main(String[] args) { SpringApplication.run(ZipkinServerApplication.class, args); } } 複製程式碼
在 配置檔案 application.yml
中指定服務埠號為 9411
,並向 Eureka
註冊中心進行 服務註冊 。
eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ server: port: 9411 spring: application: name: zipkin-server 複製程式碼
4. 構建service-hi
新建一個 Spring Boot
應用模組 service-hi
,在它的 pom.xml
中引入 引入起步依賴 spring-cloud-starter-zipkin
,完整依賴如下:
<?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 http://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>1.5.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>io.github.ostenant.springcloud</groupId> <artifactId>service-hi</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-client</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 複製程式碼
在它的 配置檔案 application.yml
中通過配置項 spring.zipkin.base-url
指定 zipkin server
的地址。
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8763 spring: application: name: service-hi zipkin: # base-url: http://localhost:9411/ # 若在同一個註冊中心的話可以啟用自動發現,省略base-url locator: discovery: enabled: true #自動發現 sleuth: sampler: percentage: 1.0 複製程式碼
到此為止 ZipKin
客戶端 已經整合完畢,最後在 應用啟動類 上對外暴露一個 API
介面 方便測試 。
@SpringBootApplication @EnableEurekaClient @RestController public class ServiceHiApplication { public static void main(String[] args) { SpringApplication.run(ServiceHiApplication.class, args); } @Value("${server.port}") private String port; @RequestMapping("/hi") public String home(@RequestParam String name) { return "Hi " + name + ", I am from port: " + port; } } 複製程式碼
5. 構建service-zuul
新建一個 Spring Boot
應用模組 service-zuul
,在 pom.xml
中引入依賴 spring-cloud-starter-zipkin
,完整依賴如下:
<?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 http://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>1.5.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>io.github.ostenant.springcloud</groupId> <artifactId>service-zuul</artifactId> <version>0.0.1-SNAPSHOT</version> <name>service-zuul</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR1</spring-cloud.version> </properties> <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> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 複製程式碼
在它的 配置檔案 application.yml
中通過配置項 spring.zipkin.base-url
指定 zipkin server
的地址。同時指定 service-hi
基於 zuul
的 服務路徑 匹配字首。
server: port: 8769 spring: application: name: service-zuul client: service-url: defaultZone: http://localhost:8761/eureka/ sleuth: sampler: percentage: 1.0 zipkin: # base-url: http://localhost:9411/ # 若在同一個註冊中心的話可以啟用自動發現,省略base-url locator: discovery: enabled: true #自動發現 zuul: routes: api-hi: path: /api-hi/** serviceId: service-hi 複製程式碼
到這裡可以發現,引入 ZipKin
服務只需要 導依賴 、 配置屬性 兩步即可。在應用的 啟動類 上使用 @EnableZuulProxy
註解開啟 路由閘道器 。
@EnableZuulProxy @EnableEurekaClient @SpringBootApplication public class ServiceZuulApplication { public static void main(String[] args) { SpringApplication.run(ServiceZuulApplication.class, args); } } 複製程式碼
6. 測試追蹤過程
完整 鏈路追蹤模組 搭建完畢,總結一下:
-
搭建一臺
zipkin server
作為 鏈路服務中心 。 -
給各個 服務 引入
zipkin
依賴,配置zipkin server
地址即可。
下面按順序依次啟動 eureka-server
、 service-zipkin
、 service-hi
和 service-zuul
。訪問服務閘道器,地址為: http://localhost:8769/api-hi/hi?name=vainlgory,服務響應內容如下:
Hi Vainlgory, I am from port: 8763
然後訪問 http://localhost:9411
,即訪問 ZipKin
提供的視覺化頁面。

這個介面用於顯示 ZipKin Server
收集的 鏈路資料 ,可以根據 服務名 、 開始時間 、 結束時間 、 請求消耗的時間 等條件來查詢。單擊 Find Tracks
按鈕,可以檢視請求的 呼叫時間 、 消耗時間 ,以及請求的 鏈路情況 。
單擊頂部的 Dependencies
按鈕,可以檢視服務的 依賴關係 。

7. 在鏈路資料中新增自定義資料
現在需要實現一個功能:在 鏈路資料 中加上請求的 操作人 。本案例在 service-zuul
閘道器服務 中實現。
-
新建一個
ZuulFilter
過濾器 ,它的型別為post
型別,order
為900
,開啟 攔截功能 。 -
在過濾器的 攔截邏輯方法
run()
裡面,通過Tracer
的addTag()
方法加上 自定義 的資料,在本案例中加上了鏈路的 操作人 。 -
也可以在這個 過濾器 中獲取 當前鏈路 的
traceld
資訊,traceld
作為 鏈路資料 的 唯一標識 ,可以儲存在log
日誌中,方便後續查詢,本案例只是將traceld
的資訊簡單地列印在控制檯上。程式碼如下:
@Component public class LoggerFileter extends ZuulFilter { @Autowired private Tracer tracer; @Override public String filterType() { return FilterConstants.POST_TYPE; } @Override public int filterOrder() { return 900; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { tracer.addTag("operator","forezp"); System.out.println(tracer.getCurrentSpan().traceIdString()); return null; } } 複製程式碼
8. 使用RabbitMQ傳輸鏈路資料
首先改造 zipkin-server
專案模組,在它的 pom.xml
檔案中將 zipkin-server
的依賴去掉,加上 spring-cloud-sleuth-zipkin-stream
和 spring-cloud-starter-stream-rabbit
的依賴,配置如下:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> 複製程式碼
在 zipkin-server
的配置檔案 application.yml
中加上 RabbitMQ
的配置,包括 主機名 、 埠 、 使用者名稱 、 密碼 ,程式碼如下:
spring: rabbitmq: host: localhost port: 5672 username: guest password: guest 複製程式碼
在應用的啟動類 ZipkinServerApplication
上把註解 @EnableZipkinServer
替換為註解 @EnableZipkinStreamServer
,開啟 ZipkinStreamServer
,程式碼如下:
@EnableEurekaClient @SpringBootApplication @EnableZipkinStreamServer public class ZipkinServerApplication { public static void main(String[] args) { SpringApplication.run(ZipkinServerApplication.class, args); } } 複製程式碼
現在來改造 Zipkin Client
(包括 service-zuul
和 service-hi
兩個模組),分別在它們的 pom.xml
檔案中將 spring-cloud-starter-zipkin
依賴改為 spring-cloud-sleuth-zipkin-stream
和 spring-cloud-starter-stream-rabbit
,程式碼如下:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> 複製程式碼
和前面的 zipkin-server
模組一樣,同時在配置檔案 applicayion.yml
加上 RabbitMQ
的配置。這樣,就將鏈路的 資料上傳 從 HTTP
改為用 訊息代元件 RabbitMQ
的方式。
9. 在MySQL資料庫中儲存鏈路資料
在上面的例子中, Zipkin Server
將資料儲存在 記憶體 中,一旦應用服務 重啟 ,之前的 鏈路資料全部丟失 ,這時候就需要引入 持久化機制 。 Zipkin
支援將 鏈路資料 儲存在 MySQL
、 Elasticsearch
和 Cassandra
資料庫中。本節講解如何使用 MySQL
儲存。
Zipkin Client
有兩種方式將 鏈路資料 傳輸到 Zipkin Server
中,一種是使用 HTTP
,另一種是使用 RabbitMQ
。 Zipkin Server
通過這兩種方式來 收集鏈路資料 ,並存儲在 MySQL
中。
9.1. 使用HTTP傳輸鏈路資料
在 zipkin-server
模組的 pom.xml
檔案加上以下依賴:
-
Zipkin Server
的依賴zipkin-server
-
Zipkin
的MySQL
儲存依賴zipkin-storage-mysql
-
Zipkin Server
的UI
介面依賴zipkin-autoconfigure-ui
-
MySQL
的聯結器依賴mysql-connector-java
-
JDBC
的 起步依賴spring-boot-starter-jdbc
程式碼如下:
<dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-server</artifactId> <version>1.19.0</version> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-storage-mysql</artifactId> <version>1.19.0</version> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> 複製程式碼
在 zipkin-server
模組的 配置檔案 application.yml
中加上 資料來源 的配置,包括 資料庫 的 Url
、 使用者名稱 、 密碼 和 連線驅動 ,並且需要配置 zipkin.storage.type
為 mysql
,程式碼如下:
spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/spring-cloud-zipkin?useUnicode=true&characterEncoding=utf8&useSSL=false username: root password: 123456 zipkin: storage: type: mysql 複製程式碼
另外需要在 MySQL
資料庫中放置資料庫的 初始化指令碼 ,建立包括 zipkin_spans
、 zipkin_annotations
和 zipkin_dependencies
這幾張表。
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, `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' ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate'; ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations'; 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(`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'; ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces'; 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 ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`); 複製程式碼
最後需要在應用的啟動類 ZipkinServerApplication
中注入 MySQLStorage
的 Bean
,程式碼如下:
@Bean public MySQLStorage mySQLStorage(DataSource datasource) { return MySQLStorage.builder() .datasource(datasource) .executor(Runnable::run) .build(); } 複製程式碼
只需要上述步驟,即可將使用 HTTP
傳輸的 鏈路資料 儲存在 MySQL
資料庫中。
9.2. 使用RabbitMQ傳輸鏈路資料
本節的案例是在使用 RabbitMQ
傳輸資料 基礎上進行改造的,只需要改造 zipkin-server
的工程。
在 zipkin-server
工程的 pom.xml
檔案中加上 MySQL
的 聯結器依賴 mysql-connector-java
和 JDBC
的 起步依賴 spring-boot-starter-jdbc
,程式碼如下:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> 複製程式碼
在 zipkin-server
模組的 配置檔案 application.yml
中加上 資料來源 的配置,包括資料庫的 Uri
、 使用者名稱 、 密碼 和 連線驅動 ,同樣的配置 zipkin.storage.type
為 mysql
,程式碼如下:
spring: datasource: url: jdbc:mysql://localhost:3306/spring-cloud-zipkin?useUnicode=true&characterEncoding=utf8&useSSL=false username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver zipkin: storage: type: mysql 複製程式碼
另外需要在 MySQL
資料庫中初始化 資料庫指令碼 ,具體同上一節。
10. 在ElasticSearch中儲存鏈路資料
在 併發高 的情況下,使用 MySQL
儲存 鏈路資料 顯然不合理,這時可以選擇使用 ElasticSearch
作為儲存。
下載並安裝 ElasticSearch
和 Kibana
,下載地址為 www.elastic.co/products/el… 。安裝完成後啟動,其中 ElasticSearch
的 預設埠號 為 9200
, Kibana
的 預設埠號 為 5601
。
本節是在 第八節 的基礎上進行改造。首先在 pom.xml
檔案中加上 zipkin
的依賴和 zipkin-autoconfigure-storage-elasticsearch-http
的依賴,程式碼如下:
<dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin</artifactId> <version>1.28.1</version> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId> <version>1.28.1</version> </dependency> 複製程式碼
在應用的配置檔案 application.yml
中加上 Zipkin
的配置,配置了 zipkin
的 儲存型別 ( type
) 為 Elasticsearch
,使用的 儲存元件 ( StorageComponent
)為 Elasticsearch
,然後需要配置 Elasticsearch
,包括 hosts
( 可以配置 多個實 例,用 “,”
隔開)。具體配置程式碼如下:
zipkin: storage: type: elasticsearch StorageComponent: elasticsearch elasticsearch: cluster: elasticsearch max-requests: 30 index: zipkin index-shards: 3 index-replicas: 1 hosts: localhost:9200 複製程式碼
只需要完成這些配置, Zipkin Server
的 鏈路資料 就可以儲存在 ElasticSearch
裡面。
11. 用Kibana展示鏈路資料
上一節講述瞭如何將 鏈路資料 儲存在 ElasticSearch
中, ElasticSearch
可以和 Kibana
結合,將 鏈路資料 展示在 Kibana
上。安裝完成後啟動 Kibana
, Kibana
預設會向 本地埠 為 9200
的 ElasticSearch
讀取資料。 Kibana
的 預設埠 為 5601
,訪問 Kibana
的主頁 http://localhost:5601
。
單擊 Management
按鈕,然後單擊 Add New
,新增一個 index
。上一節 ElasticSearch
中寫入 鏈路資料 的 index
配置的是 zipkin
,在 Kibana
介面上填寫 zipkin-*
,單擊 Create
按鈕,建立完成 index
後,單擊 Discover
,頁面上出現 鏈路資料 。