通過上一篇 《分布式服務跟蹤(整合logstash)》 ,我們雖然已經能夠利用ELK平台提供的收集、存儲、搜尋等強大功能,對跟蹤資訊的管理和使用已經變得非常便利。但是,在ELK平台中的資料分析次元缺少對請求鍊路中各階段時間延遲的關注,很多時候我們追溯請求鍊路的一個原因是為了找出整個調用鍊路中出現延遲過高的瓶頸源,亦或是為了實作對分布式系統做延遲監控等與時間消耗相關的需求,這時候類似ELK這樣的日志分析系統就顯得有些乏力了。對于這樣的問題,我們就可以引入Zipkin來得以輕松解決。
https://blog.didispace.com/spring-cloud-starter-dalston-8-4/#Zipkin%E7%AE%80%E4%BB%8B Zipkin簡介
Zipkin是Twitter的一個開源項目,它基于Google Dapper實作。我們可以使用它來收集各個伺服器上請求鍊路的跟蹤資料,并通過它提供的REST API接口來輔助我們查詢跟蹤資料以實作對分布式系統的監控程式,進而及時地發現系統中出現的延遲升高問題并找出系統性能瓶頸的根源。除了面向開發的API接口之外,它也提供了友善的UI元件來幫助我們直覺的搜尋跟蹤資訊和分析請求鍊路明細,比如:可以查詢某段時間内各使用者請求的處理時間等。

上圖展示了Zipkin的基礎架構,它主要有4個核心元件構成:
- Collector:收集器元件,它主要用于處理從外部系統發送過來的跟蹤資訊,将這些資訊轉換為Zipkin内部處理的Span格式,以支援後續的存儲、分析、展示等功能。
- Storage:存儲元件,它主要對處理收集器接收到的跟蹤資訊,預設會将這些資訊存儲在記憶體中,我們也可以修改此存儲政策,通過使用其他存儲元件将跟蹤資訊存儲到資料庫中。
- RESTful API:API元件,它主要用來提供外部通路接口。比如給用戶端展示跟蹤資訊,或是外接系統通路以實作監控等。
- Web UI:UI元件,基于API元件實作的上層應用。通過UI元件使用者可以友善而有直覺地查詢和分析跟蹤資訊。
https://blog.didispace.com/spring-cloud-starter-dalston-8-4/#HTTP%E6%94%B6%E9%9B%86 HTTP收集
在Spring Cloud Sleuth中對Zipkin的整合進行了自動化配置的封裝,是以我們可以很輕松的引入和使用它,下面我們來詳細介紹一下Sleuth與Zipkin的基礎整合過程。主要分為兩步:
第一步:搭建Zipkin Server
- 建立一個基礎的Spring Boot應用,命名為
,并在zipkin-server
中引入Zipkin Server的相關依賴,具體如下:pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 建立應用主類
,使用ZipkinApplication
注解來啟動Zipkin Server,具體如下:@EnableZipkinServer
@EnableZipkinServer
@SpringBootApplication
public class ZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinApplication.class, args);
}
}
- 在
中做一些簡單配置,比如:設定服務端口号為application.properties
(用戶端整合時候,自動化配置會連接配接9411
端口,是以在服務端設定了端口為9411
的話,用戶端可以省去這個配置)。9411
spring.application.name=zipkin-server
server.port=9411
建立完上述工程之後,我們将其啟動起來,并通路
http://localhost:9411/
,我們可以看到如下圖所示的Zipkin管理頁面:
第二步:為應用引入和配置Zipkin服務
在完成了Zipkin Server的搭建之後,我們還需要對應用做一些配置,以實作将跟蹤資訊輸出到Zipkin Server。我們以之前實作的
trace-1
和
trace-2
為例,對它們做以下改造内容:
-
trace-1
的trace-2
中引入pom.xml
依賴,具體如下所示。spring-cloud-sleuth-zipkin
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
-
trace-1
trace-2
中增加Zipkin Server的配置資訊,具體如下所示(如果在application.properties
應用中,我們将其端口設定為zip-server
,并且均在本地調試的話,該參數也可以不配置,因為預設值就是9411
)。http://localhost:9411
spring.zipkin.base-url=http://localhost:9411
測試與分析
到這裡我們已經完成了接入Zipkin Server的所有基本工作,我們可以繼續将
eureka-server
、
trace-1
trace-2
啟動起來,然後我們做一些測試實驗,以對它的運作機制有一些初步的了解。
我們先來向
trace-1
的接口發送幾個請求:
http://localhost:9101/trace-1
,當我們在日志中出現跟蹤資訊的最後一個值為
true
的時候,說明該跟蹤資訊會輸出給Zipkin Server,是以此時我們可以去Zipkin Server的管理頁面中選擇合适的查詢條件後,點選
Find Traces
,就可以查詢出剛才在日志中出現的跟蹤資訊了(也可以根據日志中的Trace ID,在頁面的右上角輸入框中來搜尋),具體如下頁面所示:
點選下方
trace-1
端點的跟蹤資訊,我們還可以得到Sleuth收集到的跟蹤到詳細資訊,其中包括了我們關注的請求時間消耗等。
點選導航欄中的
Dependencies
菜單,我們還可以檢視Zipkin Server根據跟蹤資訊分析生成的系統請求鍊路依賴關系圖:
消息中間件收集
Spring Cloud Sleuth在整合Zipkin時,不僅實作了以HTTP的方式收集跟蹤資訊,還實作了通過消息中間件來對跟蹤資訊進行異步收集的封裝。通過結合Spring Cloud Stream,我們可以非常輕松的讓應用用戶端将跟蹤資訊輸出到消息中間件上,同時Zipkin服務端從消息中間件上異步地消費這些跟蹤資訊。
接下來,我們基于之前實作的
trace-1
trace-2
應用以及
zipkin-server
服務端做一些改造,以實作通過消息中間件來收集跟蹤資訊。改造的内容非常簡單,隻需要我們做項目依賴和配置檔案做一些調整就能馬上實作,下面我們分别對用戶端和服務端的改造内容做詳細說明:
第一步:修改用戶端
trace-1
trace-2
- 為了讓
trace-1
在産生跟蹤資訊之後,能夠将抽樣記錄輸出到消息中間件中,我們除了需要之前引入的trace-2
依賴之外,還需要引入zipkin對Spring Cloud Stream的擴充依賴spring-cloud-starter-sleuth
以及基于Spring Cloud Stream實作的消息中間件綁定器依賴,以使用RabbitMQ為例,我們可以加入如下依賴:spring-cloud-sleuth-stream
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
-
配置中去掉HTTP方式實作時使用的application.properties
參數,并根據實際部署情況,增加消息中間件的相關配置,比如下面這些關于RabbitMQ的配置資訊:spring.zipkin.base-url
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=springcloud
spring.rabbitmq.password=123456
第二步:修改
zipkin-server
服務端
zipkin-server
服務端能夠從消息中間件中擷取跟蹤資訊,我們隻需要在
pom.xml
中引入針對消息中間件收集封裝的服務端依賴
spring-cloud-sleuth-zipkin-stream
,同時為了支援具體使用的消息中間件,我們還需要引入針對消息中間件的綁定器實作,比如以使用RabbitMQ為例,我們可以在依賴中增加如下内容:
<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>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency>
其中,
spring-cloud-sleuth-zipkin-stream
依賴是實作從消息中間件收集跟蹤資訊的核心封裝,其中包含了用于整合消息中間件的核心依賴、zipkin服務端的核心依賴、以及一些其他通常會被使用的依賴(比如:用于擴充資料存儲的依賴、用于支援測試的依賴等)。但是,需要注意的是這個包裡并沒有引入
zipkin
的前端依賴
zipkin-autoconfigure-ui
,為了友善使用,我們在這裡也引用了它。
在完成了上述改造内容之後,我們繼續将
eureka-server
trace-1
trace-2
zipkin-server
都啟動起來,同時確定RabbitMQ也處于運作狀态。此時,我們可以在RabbitMQ的控制頁面中看到一個名為
sleuth
的交換器,它就是zipkin的消息中間件收集器實作使用的預設主題。
最後,我們使用之前的驗證方法,通過向
trace-1
http://localhost:9101/trace-1
,當有被抽樣收集的跟蹤資訊時(調試時我們可以設定
AlwaysSampler
抽樣機制來讓每個跟蹤資訊都被收集),我們可以在RabbitMQ的控制頁面中發現有消息被發送到了
sleuth
交換器中,同時我們再到zipkin服務端的Web頁面中也能夠搜尋到相應的跟蹤資訊,那麼我們使用消息中間件來收集跟蹤資訊的任務到這裡就完成了。
https://blog.didispace.com/spring-cloud-starter-dalston-8-4/#%E5%AE%8C%E6%95%B4%E7%A4%BA%E4%BE%8B%EF%BC%9A 完整示例:
讀者可以根據喜好選擇下面的兩個倉庫中檢視
trace-1
trace-2
兩個項目:
- Github:https://github.com/dyc87112/SpringCloud-Learning/
- Gitee:https://gitee.com/didispace/SpringCloud-Learning/
如果您對這些感興趣,歡迎star、follow、收藏、轉發給予支援!
本文内容部分節選自我的《Spring Cloud微服務實戰》,但對依賴的Spring Boot和Spring Cloud版本做了更新。