前言
在spring cloud分布式架構中,系統被拆分成了許多個服務單元,業務復雜性提高。如果出現了異常情況,很難定位到錯誤位置,所以需要實現分布式鏈路追蹤,跟進一個請求有哪些服務參與,參與的順序如何,從而去明確一個問題。
spring cloud sleuth
通常來說,一個分布式服務跟蹤系統主要由三部分:數據收集、數據存儲和數據展示。
對於大規模的分布式系統來說,數據存儲可分為實時數據和全量數據兩部分。實時數據用來排查故障,全量數據用於系統優化;數據展示涉及數據挖掘和分析。
- 名詞解釋
服務追蹤的追蹤單元是從客戶端發起請求抵達被追蹤的系統邊界開始,到被追蹤的邊界開始,到被追蹤的紫銅向客戶返回響應為止的過程,稱呼為一個 "trace"。每個 trace
中會調用若干個服務,為了記錄調用了哪些服務,以及每次調用的響應時間等信息,在調用每個服務時,都會邁入一個調用記錄,成為一個 "span"。如此,若干個有序的 span
就組成了一個 trace
。
在系統向外界提供服務的過程中,會不斷地有請求和響應發生,也就會不斷生成 trace
,把這些帶有span
的 trace
記錄下來,就可以描繪出一幅系統的服務拓撲圖。附帶上 span
中的響應時間,以及請求成功與否等信息,就可以在發生問題的時候,找到異常的服務;根據歷史數據,還可以從系統整體層面分析出哪里性能差,定位性能優化的目標。
spring cloud sleuth 為服務之間提供鏈路追蹤。我們可以清楚的認識到一個請求經過了哪些服務,每個服務處理花了多長時間,理清服務之間的調用關系和順序
spring cloud sleuth 主要提供了數據收集部分功能,因此需要結合 zipkin,將信息發送到zipkin,利用zipkin的存儲來存儲信息,利用zipkin ui來展示數據。
zipkin
Zipkin 是一個開放源代碼分布式的跟蹤系統,由Twitter公司開源,主要用於數據的存儲、查找和展示。 zipkin 提供了可拔插數據存儲方式,生產環境中推薦使用 Elasticsearch,還能結合 kibana 使用。
Zipkin 和 Config 結構類似,分為服務端 Server,客戶端Client,客戶端就是各個微服務應用。
具體使用
zipkin-server服務端
在Spring boot 2.0版本之后,官方不再推薦支持自己搭建服務,而是直接提供編譯好的jar包,直接運行jar包,啟動服務,非常方便。還有docker啟動,Running from Source
等,具體的可以在官網查看,鏈接:https://zipkin.io/pages/quickstart.html
Docker方式(quickest)
docker run -d -p 9411:9411 openzipkin/zipkin
java(終端命令模式)
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
備注:必須環境為java8及其以上。jar包下載地址:https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec
運行
瀏覽器啟動地址http://localhost:9411/zipkin/
,成功之后看到如下界面
客戶端
項目依賴(maven)
- 僅僅使用Spring Cloud Sleuth,不包含Zipkin
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
- 同時使用Spring Cloud Sleuth + Zipkin(HTTP查看)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
- 使用RabbitMQ或Kafka而不是HTTP
如果使用Kafka,則必須相應地設置property spring.zipkin.sender.type屬性:
spring.zipkin.sender.type: kafka
注意:
spring-cloud-sleuth-stream
已不推薦使用,現已不兼容。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
</dependency>
詳情見官網:https://cloud.spring.io/spring-cloud-sleuth/reference/html/#sleuth-adding-project
- 實例
在所有服務中引入
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-zipkin</artifactId>
</dependency>
</dependencies>
Spring應用在監測到Java依賴包中有sleuth和zipkin后,會自動在RestTemplate的調用過程中向HTTP請求注入追蹤信息,並向Zipkin Server發送這些信息。
配置文件(建議application.yml)
server:
port: 9400
spring:
application:
name: zipkin-server
zipkin:
base-url: http://ivms.io:9411
sender:
type: web
sleuth:
sampler:
probability: 0.1
rate: 2
eureka:
client:
serviceUrl:
defaultZone: http://192.168.2.42:8761/eureka/
logging:
level:
root: debug
Spring Cloud Sleuth有一個Sampler策略,可以通過這個實現類來控制采樣算法。默認采樣率為0.1,即10%,這里設置 1.0,全部采樣。
注意一下,版本不同,所使用的配置也不同。sender.type需要手動指定,默認是rabbitmq,不然會導致zipkin界面沒有客戶端連接。還有sleuth.sampler中的percentage現在也變成了rate,要注意,之后也可能會再變化,跟着版本走,別人的例子都是參考一個大致方向
啟動服務
然后把測試服務啟動,隨便請求一個接口
- 控制台輸出
會發現有這樣子的東西打印,這是好事,證明追蹤到了請求記錄。解釋一下:
-
第一個值
zipkin-client1
,記錄了應用的名稱 -
第二個
a942e108d3baceb8
,是 Spring Cloud Sleuth 生成的一個 ID,稱為 Trace ID,它用來標識一條請求鏈路。一條請求鏈路中包含一個 Trace ID,多個 Span ID。(上面說過了) -
第三個就是
spanID
了,它表示一個基本的工作單元,比如發送一個 HTTP 請求。 -
true
代表是否要將該信息輸出到 Zipkin Server 中來收集和展示。因為我們設置了采集率1.0,所以自然是true
- zaipkin UI展示
然后就看一下瀏覽器顯示什么吧,打開 http://localhost:9411/zipkin/
可以看到Service Name
中多了一個東西 zipkin-client1(我的服務名,這不是什么專業名詞哈),然后點擊 Find Traces 就可以看到一條服務調用記錄
可以看到上面顯示了服務調用耗時,請求數量,是否成功,然后點擊記錄可以看到服務調用鏈路關系,點擊依賴分析可以看到服務之間的依賴關系,自己嘗試一下
結語:很簡單,但我花了兩天,因為升級之后完全大改,網上也沒有資料,只能去看官網文檔,更坑的是中文網和官網寫的不一樣(對比spring cloud sleuth),攤手。之后會結合 gateway、ELK 實踐一下,緣分更新。