接上篇文章:https://blog.csdn.net/qq_33333654/article/details/103389470
參考文獻:http://www.ityouknow.com/springcloud/2018/02/02/spring-cloud-sleuth-zipkin.html
demo代碼地址:https://download.csdn.net/download/qq_33333654/12014918
隨着業務發展,系統拆分導致系統調用鏈路愈發複雜一個前端請求可能最終需要調用很多次後端服務才能完成,當整個請求變慢或不可用時,我們是無法得知該請求是由某個或某些後端服務引起的,這時就需要解決如何快讀定位服務故障點,以對症下藥。於是就有了分佈式系統調用跟蹤的誕生。
現今業界分佈式服務跟蹤的理論基礎主要來自於 Google 的一篇論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,使用最爲廣泛的開源實現是 Twitter 的 Zipkin,爲了實現平臺無關、廠商無關的分佈式服務跟蹤,CNCF 發佈了布式服務跟蹤標準 Open Tracing。國內,淘寶的“鷹眼”、京東的“Hydra”、大衆點評的“CAT”、新浪的“Watchman”、唯品會的“Microscope”、窩窩網的“Tracing”都是這樣的系統。
Spring Cloud Sleuth
一般的,一個分佈式服務跟蹤系統,主要有三部分:數據收集、數據存儲和數據展示。根據系統大小不同,每一部分的結構又有一定變化。譬如,對於大規模分佈式系統,數據存儲可分爲實時數據和全量數據兩部分,實時數據用於故障排查(troubleshooting),全量數據用於系統優化;數據收集除了支持平臺無關和開發語言無關係統的數據收集,還包括異步數據收集(需要跟蹤隊列中的消息,保證調用的連貫性),以及確保更小的侵入性;數據展示又涉及到數據挖掘和分析。雖然每一部分都可能變得很複雜,但基本原理都類似。
服務追蹤的追蹤單元是從客戶發起請求(request)抵達被追蹤系統的邊界開始,到被追蹤系統向客戶返回響應(response)爲止的過程,稱爲一個“trace”。每個 trace 中會調用若干個服務,爲了記錄調用了哪些服務,以及每次調用的消耗時間等信息,在每次調用服務時,埋入一個調用記錄,稱爲一個“span”。這樣,若干個有序的 span 就組成了一個 trace。在系統向外界提供服務的過程中,會不斷地有請求和響應發生,也就會不斷生成 trace,把這些帶有span 的 trace 記錄下來,就可以描繪出一幅系統的服務拓撲圖。附帶上 span 中的響應時間,以及請求成功與否等信息,就可以在發生問題的時候,找到異常的服務;根據歷史數據,還可以從系統整體層面分析出哪裏性能差,定位性能優化的目標。
Spring Cloud Sleuth爲服務之間調用提供鏈路追蹤。通過Sleuth可以很清楚的瞭解到一個服務請求經過了哪些服務,每個服務處理花費了多長。從而讓我們可以很方便的理清各微服務間的調用關係。此外Sleuth可以幫助我們:
- 耗時分析: 通過Sleuth可以很方便的瞭解到每個採樣請求的耗時,從而分析出哪些服務調用比較耗時;
- 可視化錯誤: 對於程序未捕捉的異常,可以通過集成Zipkin服務界面上看到;
- 鏈路優化: 對於調用比較頻繁的服務,可以針對這些服務實施一些優化措施。
spring cloud sleuth可以結合zipkin,將信息發送到zipkin,利用zipkin的存儲來存儲信息,利用zipkin ui來展示數據。
這是Spring Cloud Sleuth的概念圖:
創建zipkin-server項目
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>zipkin-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>zipkin-server</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Dalston.RELEASE</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-server</artifactId> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
yml文件:
server: port: 9000 eureka: client: service-url: defaultZone: http://peer1:8000/eureka/,http://peer2:8001/eureka/,http://peer3:8002/eureka/ spring: application: name: zipkin-server
啓動類:
package com.example.zipkinserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import zipkin.server.EnableZipkinServer; @EnableEurekaClient @EnableZipkinServer @SpringBootApplication public class ZipkinServerApplication { public static void main(String[] args) { SpringApplication.run(ZipkinServerApplication.class, args); } }
@EnableZipkinServer是添加對zipink的支持
啓動註冊中心,啓動rabbitmq,啓動zipkin-server項目,瀏覽器訪問:
說明啓動成功。
zuul項目添加支持:
zuul項目pom添加:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
zuul項目添加yml支持:
server: port: 8888 eureka: client: service-url: defaultZone: http://peer1:8000/eureka/,http://peer2:8001/eureka/,http://peer3:8002/eureka/ spring: application: name: gateway-service-zuul # cloud: # loadbalancer: # retry: # enabled: true # 開啓重試 zipkin: base-url: http://localhost:9000 sleuth: sampler: percentage: 1.0 zuul: routes: api-a: path: /client/** serviceId: spring-cloud-config-client retryable: true # 開啓重試 ribbon: # connectTimeout: 2000 # 請求連接的超時時間 # readTimeout: 5000 # 請求處理的超時時間 maxAutoRetries: 2 # 對當前實例的重試次數 maxAutoRetriesNextServer: 0 # 切換實例的重試次數 # okToRetryOnAllOperations: false # 對所有操作請求都進行重試 # hello: # path: /hello/** # url: http://localhost:9031/ # baidu: # path: /it/** # url: https://blog.csdn.net/qq_33333654/category_9436879.html
spring-cloud-config-client項目添加zipkin支持:
pom文件:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
修改bootstrap.yml文件:
spring: zipkin: base-url: http://localhost:9000 sleuth: sampler: percentage: 1.0 cloud: config: discovery: enabled: true serviceId: spring-cloud-config-server # uri: http://localhost:9021/ name: native profile: mysql lable: master eureka: client: service-url: defaultZone: http://peer1:8000/eureka/,http://peer2:8001/eureka/,http://peer3:8002/eureka/
特別注意,這裏必須添加到bootstrap.yml文件中,最好是放到上面。不然會報錯Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
接下來一次啓動:
spring-cloud-config-server項目、
spring-cloud-config-client項目、
zuul項目。
注意瀏覽器訪問前清理下緩存。
瀏覽器訪問http://localhost:8888/client/testZuul?token=xxx
多次訪問後,瀏覽器打開http://localhost:9000
點擊按鈕,如圖:
追蹤結果:
查看追蹤圖譜,點擊如圖按鈕:
完成。