一、介紹
SpringCloud Sleuth爲微服務提供了調用鏈路追蹤解決方案,並且兼容支持了Zipkin,只需要引入相應的依賴,配置,即可實現對鏈路的監控。
SpringCloud Sleuth可以追蹤10種組件:async、Hystrix、messaging、websocket、rxjava、scheduling、web(Spring MVC Controller, Servlet)、webclient(Spring RestTemplate)、Feign、Zuul 。可以參考 Spring Cloud Sleuth消息追蹤原理,該博客介紹了Sleuth對8中常用組件的追蹤原理。
SpringCloud對Zipkin進行了有效的集成,Zipkin是Twitter開源的輕量級分佈式鏈路調用監控系統。Zipkin易於搭建,但是監控的東西很簡單。pinpoint以及skywalking不僅僅提供了分佈式服務的跟蹤能力,還提供了其他性能監控,是一個APM解決方案。
分佈式服務追蹤系統主要有一下三個關鍵點:
1. Span。一個基礎工作單元(例如服務調用)。爲了統計各處理單元的時間延遲,當請求到達各服務組件時,也通過一個唯一標識(Span ID)標記它的開始、具體過程、結束。通過Span的開始和結束的時間戳,就能統計這個Span的時間延遲,獲取事件名稱、請求信息等元數據。
2. Trace。 一系列Span組成的樹狀結構。所有Span通過相同的Trace串聯組成。爲了實現請求跟蹤,當請求到一個分佈式系統的入口端點時,只需要服務跟蹤框架爲該請求創建一個唯一的跟蹤標識(Trace ID),同時在服務內部流轉時始終保持傳遞該唯一標識,直到請求返回爲止。框架通過它將請求過程中的日誌關聯起來。
3. Annotation。用來及時記錄一個事件的存在,一些核心Annotation用來定義請求的開始和結束。
● cs(Client Sent):客戶端發出一個請求,這個Annotation描述了這個Span的開始。
● sr(Server Received):服務端收到請求並開始處理。timestampsr-timesampcs=網絡延遲。
● ss(Server Sent):服務器處理完並準備返回給客戶端。timestampss-timesampsr=服務器處理時間。
● cr(Client Received):客戶端收到響應,表明Span的結束。timestampcr-timestampcs=請求總時間。
二、Zipkin結構與傳輸
下圖更能體現Zipkin的工作流程。
跟蹤工具報告是異步的,避免跟蹤系統對服務造成延時或故障。
Client收到服務的響應後,異步發送給Zipkin,Zipkin Collecter守護程序收到追蹤數據,Zipkin Collecter就會對追蹤數據進行驗證、存儲、索引。
Transport
追蹤數據要從Span傳輸到Zipkin Collector服務,有三種主要的傳輸方式:Http,MQ(kafka),Scribe。
Components
Collector:一旦數據到達了Zipkin Collector的守護程序,就會被收集。
Storage:默認內存。Cassandra最初是爲了存Zipkin數據而建立的,因爲Cassandra可拓展。Cassandra可插拔,所以通常用ES,Mysql等替代。
Query Service:一旦數據被存儲或者索引,我們就要用一種方法提取數據。查詢守護進程提供一個簡單的JSON API用於查找和檢索跟蹤。這個API的主要使用者是Web UI。
Web UI:提供了基於服務、時間、註釋查看跟蹤的方法。(沒有內置的身份驗證機制)
三、創建一個Zipkin Server
1. 導入web依賴,以及Zipkin Server、Zipkin UI的依賴
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency>
2. 開啓@EnableZipkinServer註解@SpringBootApplication
@EnableZipkinServer
public class ZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinApplication.class, args);
}
}
3. 修改配置文件,設置端口spring.application.name=sleuth-service
server.port=8770
四、創建service-1,service-2, service-1通過RestTemplate調用service-2
1. 引入web、Sleuth、Zipkin依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
2. 兩個工程創建兩個接口,service-1的接口調用service-2的接口
service-1:
@SpringBootApplication
@RestController
public class Service1Application {
public static void main(String[] args) {
SpringApplication.run(Service1Application.class, args);
}
@Autowired
RestTemplate restTemplate;
@Bean
RestTemplate getRestTemplate(){
return new RestTemplate();
}
@RequestMapping("/service2")
public String callService2(){
return restTemplate.getForObject("http://localhost:8772/call", String.class);
}
}
service-2:@SpringBootApplication
@RestController
public class Service2Application {
@Autowired
RestTemplate restTemplate;
@Bean
RestTemplate getRestTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(Service2Application.class, args);
}
@RequestMapping("/call")
public String call(){
return "service-2 called..";
}
}
3. 增加配置
service-1:
server.port=8771
spring.application.name=service-1
spring.zipkin.base-url=http://localhost:8770
spring.sleuth.sampler.percentage=1
service-2:server.port=8772
spring.application.name=service-2
spring.zipkin.base-url=http://localhost:8770
spring.sleuth.sampler.percentage=1
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
注意:這裏要配置採樣率spring.sleuth.sampler.percentage=1,如果不配置這裏默認爲0.1,如果調大值爲1,可以在Web UI上更及時看到信息。但是調大會影響服務調用速率。
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
五、測試
先啓動Zipkin Server,訪問 http:localhost:8770/
啓動兩個服務, 訪問service-1中調用service-2的接口 localhost:8771/service2
再刷新Zipkin UI的Dependencies
trace: