服務調用鏈路追蹤
微服務架構是一個分布式架構,它按業務划分服務單元,一個分布式系統往往有很多個服務單元。由於服務單元數量眾多,業務的復雜性,如果出現了錯誤和異常,很難去定位。主要體現在,一個請求可能需要調用很多個服務,而內部服務的調用復雜性,決定了問題難以定位。所以微服務架構中,必須實現分布式鏈路追蹤,去跟進一個請求到底有哪些服務參與,參與的順序又是怎樣的,從而達到每個請求的步驟清晰可見,出了問題,很快定位。
舉個例子,在微服務系統中,一個來自用戶的請求,請求先達到前端A(如前端界面),然后通過遠程調用,達到系統的中間件B、C(如負載均衡、網關等),最后達到后端服務D、E,后端經過一系列的業務邏輯計算最后將數據返回給用戶。對於這樣一個請求,經歷了這么多個服務,怎么樣將它的請求過程的數據記錄下來呢?這就需要用到服務鏈路追蹤。
Google開源的 Dapper鏈路追蹤組件,並在2010年發表了論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,這篇文章是業內實現鏈路追蹤的標桿和理論基礎,具有非常大的參考價值。
常見的業界開源解決方案
1、Dapper(谷歌)
2、Zikpin,與Spring Cloud Sleuth結合的比較好
3、Eagleeye(阿里)
4、pinpoint
5、skywalking
本文主要講述如何在Spring Cloud Sleuth中集成Zipkin。在Spring Cloud Sleuth中集成Zipkin非常的簡單,只需要引入相應的依賴和做相關的配置即可。
Spring Cloud Sleuth簡介
Spring Cloud Sleuth為Spring Cloud實現了分布式跟蹤解決方案。
術語
Span:基本工作單元。例如,發送RPC是一個新的跨度,就像發送響應到RPC一樣。跨度由跨度的唯一64位ID和跨度所屬的跟蹤的另一個64位ID標識。跨區還具有其他數據,例如描述,帶有時間戳的事件,鍵值注釋(標簽),引起跨度的跨區ID和進程ID(通常為IP地址)。
跨度可以啟動和停止,並且可以跟蹤其時序信息。創建跨度后,您必須在將來的某個時間點將其停止。
PUT
請求形成。
Annotation:用來及時記錄一個事件的,一些核心注解用來定義一個請求的開始和結束 。這些注解包括以下:
-
- cs:客戶端已發送。客戶提出了要求。此注釋指示跨度的開始。
- sr:接收到服務器:服務器端收到了請求並開始處理它。從此時間戳中減去
cs
時間戳可顯示網絡延遲。 - ss:服務器已發送。在請求處理完成時進行注釋(當響應被發送回客戶端時)。從此時間戳中減去
sr
時間戳將顯示服務器端處理請求所需的時間。 - cr:收到客戶。表示跨度結束。客戶端已成功收到服務器端的響應。從此時間戳中減去
cs
時間戳將顯示客戶端從服務器接收響應所需的整個時間。
圖顯示了Span和Trace在系統中的外觀以及Zipkin批注:
音符的每種顏色都表示一個跨度(從A到G共有七個spans- )。請考慮以下注意事項:
Trace Id = X Span Id = D Client Sent
該說明指出,當前跨距跟蹤編號設定為X和Span標識設置為d。同樣,發生了Client Sent
事件。
下圖顯示了spans的父子關系:
Zipkin簡介
Zipkin是一個分布式跟蹤系統。它有助於收集解決服務體系結構中的延遲問題所需的時序數據。功能包括該數據的收集和查找。
鏈路追蹤案例
架構圖
Zipkin服務端搭建
1、下載Zipkin服務端jar包,可以去網關下載,也可以去地址:https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/
2、使用命令啟動Zipkin服務端,命令:java -jar zipkin-server-2.12.9-exec.jar
3、使用瀏覽器訪問地址:http://127.0.0.1:9411,9411是Zipkin的默認端口
Sleuth服務提供者項目搭建
Eureka注冊中心搭建參考:【SpringCloud】快速入門(一)
1、新建一個模塊(springcloud-provider-sleuth-payment8010)作為Sleuth服務提供者
2、修改pom文件,引入依賴zipkin + sleuth,以及eureka
1 <!-- zipkin + sleuth --> 2 <dependency> 3 <groupId>org.springframework.cloud</groupId> 4 <artifactId>spring-cloud-starter-zipkin</artifactId> 5 </dependency> 6 7 <!-- eureka client --> 8 <dependency> 9 <groupId>org.springframework.cloud</groupId> 10 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 11 </dependency>
查看spring-cloud-starter-zipkin依賴,可以看到它包含了spring-cloud-starter-sleuth以及spring-cloud-starter-sleuth-zipkin依賴
完整pom文件如下:

1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>test-springcloud</artifactId> 7 <groupId>com.test</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>springcloud-provider-sleuth-payment8010</artifactId> 13 14 <dependencies> 15 16 <!-- zipkin + sleuth --> 17 <dependency> 18 <groupId>org.springframework.cloud</groupId> 19 <artifactId>spring-cloud-starter-zipkin</artifactId> 20 </dependency> 21 22 <!-- eureka client --> 23 <dependency> 24 <groupId>org.springframework.cloud</groupId> 25 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 26 </dependency> 27 28 <!-- spring boot --> 29 <dependency> 30 <groupId>org.springframework.boot</groupId> 31 <artifactId>spring-boot-starter-web</artifactId> 32 </dependency> 33 <dependency> 34 <groupId>org.springframework.boot</groupId> 35 <artifactId>spring-boot-starter-actuator</artifactId> 36 </dependency> 37 38 <dependency> 39 <groupId>org.springframework.boot</groupId> 40 <artifactId>spring-boot-devtools</artifactId> 41 <scope>runtime</scope> 42 <optional>true</optional> 43 </dependency> 44 45 <dependency> 46 <groupId>org.projectlombok</groupId> 47 <artifactId>lombok</artifactId> 48 <optional>true</optional> 49 </dependency> 50 <dependency> 51 <groupId>org.springframework.boot</groupId> 52 <artifactId>spring-boot-starter-test</artifactId> 53 <scope>test</scope> 54 </dependency> 55 </dependencies> 56 57 </project>
3、編輯application.yml配置文件
1 # 端口 2 server: 3 port: 8010 4 5 spring: 6 application: 7 name: cloud-sleuth-provider 8 zipkin: 9 # zipkin url地址 10 base-url: http://localhost:9411 11 sleuth: 12 sampler: 13 # 采樣率值介於 0 到 1 之間, 1 則表示全部采集 14 # 默認值:0.1,即10% 15 probability: 1 16 17 eureka: 18 client: 19 service-url: 20 defaultZone: http://localhost:8761/eureka
4、編寫啟動類
1 @SpringBootApplication 2 public class PaymentMain8010 { 3 public static void main(String[] args) { 4 SpringApplication.run(PaymentMain8010.class, args); 5 } 6 }
5、編寫Controller
1 @RestController 2 public class PaymentController { 3 4 @GetMapping("/payment/zipkin") 5 public String paymentZipkin(){ 6 return "Hi, this is payment zipkin server"; 7 } 8 }
6、測試
1)啟動Eureka注冊中心,啟動Sleuth服務提供者
2)訪問地址:http://127.0.0.1:8010/payment/zipkin,正常獲取內容
Sleuth服務消費者項目搭建
1、新建一個模塊(springcloud-consumer-sleuth-order7995)作為Sleuth服務消費者
2、修改pom文件,引入依賴zipkin + sleuth,以及eureka,內容同上
3、編輯application.yml配置文件
1 # 端口 2 server: 3 port: 7995 4 5 spring: 6 application: 7 name: cloud-order 8 zipkin: 9 base-url: http://localhost:9411 10 sleuth: 11 sampler: 12 # 采樣率值介於 0 到 1 之間, 1 則表示全部采集 13 probability: 1 14 15 eureka: 16 client: 17 service-url: 18 defaultZone: http://localhost:8761/eureka
4、編寫啟動類
1 @SpringBootApplication 2 public class OrderMain7995 { 3 public static void main(String[] args) { 4 SpringApplication.run(OrderMain7995.class, args); 5 } 6 }
5、編寫配置類
1 @Configuration 2 public class AppConfig { 3 4 /** 5 * 注入restTemplate,請用請求rest接口 6 * @return 7 */ 8 @Bean 9 // 標注此注解后,RestTemplate就具有了客戶端負載均衡能力 10 // 負載均衡技術依賴於的是Ribbon組件~ 11 // RestTemplate都塞入一個loadBalancerInterceptor 讓其具備有負載均衡的能力 12 @LoadBalanced 13 public RestTemplate restTemplate(){ 14 return new RestTemplate(); 15 } 16 }
6、編寫controller,調用服務
1 @RestController 2 public class OrderController { 3 4 @Autowired 5 private RestTemplate restTemplate; 6 7 @GetMapping("/consumer/payment/zipkin") 8 public String paymentZipkin(){ 9 String result = restTemplate.getForObject("http://CLOUD-SLEUTH-PROVIDER" + "/payment/zipkin", String.class); 10 return result; 11 } 12 13 }
7、測試
1)啟動Eureka注冊中心,啟動Sleuth服務提供者、消費者,Zipkin服務端
2)訪問地址:http://127.0.0.1:7995/consumer/payment/zipkin,正常獲取內容
3)查看Zipkin的Web界面,地址:http://127.0.0.1:9411/zipkin,點擊查詢按鈕
顯示如下,可以看到里面的請求記錄,包括:ROOT(微服務名,請求方式,請求路徑)、TRACE ID、開始時間、持續時間
4)查看最近一次請求CLOUD-ORDER的詳情數據
5)打開依賴頁面,進行搜索,可以看打時間段內,服務之間的依賴關系