Spring Cloud(九)Sleuth+ZipKin 實現服務追蹤
注:本文Spring Cloud 版本 Finchley.SR1
為什麼需要服務追蹤
微服務架構是一個分散式架構,它按業務劃分服務單元,一個分散式系統往往有很多個服務單元。由於服務單元數量眾多,業務的複雜性,如果出現了錯誤和異常,很難去定位。主要體現在,一個請求可能需要呼叫很多個服務,而內部服務的呼叫複雜性,決定了問題難以定位。所以微服務架構中,必須實現分散式鏈路追蹤,去跟進一個請求到底有哪些服務參與,參與的順序又是怎樣的,從而達到每個請求的步驟清晰可見,出了問題,很快定位。
舉個例子,在微服務系統中,一個來自使用者的請求,請求先達到前端A(如前端介面),然後通過遠端呼叫,達到系統的中介軟體B、C(如負載均衡、閘道器等),最後達到後端服務D、E,後端經過一系列的業務邏輯計算最後將資料返回給使用者。對於這樣一個請求,經歷了這麼多個服務,怎麼樣將它的請求過程的資料記錄下來呢?這就需要用到服務鏈路追蹤。
作為Java全家桶的Spring當然也考慮到了這點,也已經為我們實現了鏈路追蹤,也就是 Spring Cloud 的子專案 Spring Cloud Sleuth。 使用zipkin在收集到跟蹤資訊後將其聚合處理、儲存、展示等,使用者可通過web UI方便獲得網路延遲、呼叫鏈路、系統依賴等等。
構建zipkin-server工程
新建一個工程,取名為mz-zipkin-server
,引入Eureka的起步依賴spring-cloud-netflix-eureka-client,引入zipkin-server依賴,以及zipkin-autoconfigure-ui依賴,後兩個依賴提供了Zipkin的功能和Zipkin介面展示的功能。程式碼如下:
1、POM檔案
<dependencies>
<!--<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</ groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>${zipkin.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>${zipkin.version}</version>
</dependency>
</dependencies>
2、啟動類(Application)
@EnableZipkinServer
@SpringBootApplication
public class ZipKinApplication {
public static void main(String[] args) {
SpringApplication.run(ZipKinApplication.class, args);
}
}
3、屬性檔案
server:
port: 9411
spring:
application:
name: zipkin-server
management:
metrics:
web:
server:
auto-time-requests: false
這個時候 zipkinServer 便溝建好了,啟動訪問 http://localhost:9411 就能夠看到zipkin頁面。
改造 Client
我們在之前的專案 mz-eureka-consumer-ribbon
專案基礎上覆制兩個專案 mz-zipkin-client-one
和 mz-zipkin-client-two
,加以改造
1、引入依賴
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Feign 依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- ZipKin 依賴-->
<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>
</dependencies>
2、增加配置
spring.zipkin.base-url=http://localhost:9411
spring.sleuth.sampler.probability=1.0
#注:spring.sleuth.sampler.percentage為1.0,即100%的概率將鏈路的資料上傳給Zipkin Server,在預設的情況下,該值為0.1
3、增加介面
增加介面兩個專案互相呼叫,從而產生鏈路資料供我們檢視,這裡不再詳細貼程式碼,可以參考專案。
@RestController
public class HelloController {
@Autowired
RestTemplate restTemplate;
@Autowired
HelloFeign helloFeign;
// restTemplate 呼叫
@RequestMapping("rest")
public String sayHiByRest() {
return restTemplate.getForEntity("http://mz-zipkin-client-two/hi", String.class).getBody();
}
// feign 呼叫
@RequestMapping("feign")
public String sayHiByFeign() {
return helloFeign.sayHi();
}
// 錯誤呼叫
@RequestMapping("fail")
public String error() {
return restTemplate.getForEntity("http://mz-zipkin-client-two/hi2", String.class).getBody();
}
}
測試
1、分別啟動註冊中心、Zuul 閘道器、ZipkinServer、以及上面的 client one 、client two
2、分別請求上面的三個介面產生鏈路資料