Spring Cloud 分散式鏈路跟蹤 Sleuth + Zipkin + Elasticsearch
隨著業務越來越複雜,系統也隨之進行各種拆分,特別是隨著微服務架構的興起,看似一個簡單的應用,後臺可能很多服務在支撐;一個請求可能需要多個服務的呼叫;當請求遲緩或不可用時,無法得知是哪個微服務引起的,這時就需要解決如何快速定位服務故障點,Zipkin 分散式跟蹤系統就能很好的解決這樣的問題。
如果想學習Java工程化、高效能及分散式、深入淺出。微服務、Spring,MyBatis,Netty原始碼分析的朋友可以加我的Java高階交流:854630135,裡面有阿里大牛直播講解技術,以及Java大型網際網路技術的視訊免費分享給大家。
那麼到底怎麼使用呢?接下來完成一個具體的例項來體會一把微服務鏈路追蹤:
本文使用的 Spring Cloud Finchley 版本,和其他版本會有不同
我們使用user-service,order-service 作為兩個微服務,zuul-gateway 作為服務閘道器
zuul-gateway -> order-service -> user-service, 形成服務呼叫鏈路,完成一次請求。
注意:Zipkin 不再推薦我們來自定義 Server 端,在最新版本的 Spring Cloud 依賴管理裡已經找不到 Zipkin-server 了 ,根本就不需要自己新建一個 Zipkin-server 服務,網上的各種教程都數互相抄的,請無視
一,環境安裝
- 本人使用 centos 7 ,java-10
- 安裝 Zipkin:聚合各個業務系統之間的呼叫延遲資料
- 安裝 RabbitMQ:系統呼叫資料傳輸
- 安裝 Elasticsearch:系統呼叫資料持久化
- 安裝Elasticsearch-head:Elasticsearch 視覺化
二,建立微服務
- user-service
- 以下是pom依賴檔案
<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.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--服務鏈路追蹤--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <!--資料傳輸--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rabbit</artifactId> </dependency>
- 新建@RestController 介面 UserOrderController,程式碼如下:
@RestController public class UserOrderController { @Autowired private UserOrderService orderService; @RequestMapping(value = "/getUserOrder", method = RequestMethod.GET) public String getUserOrder() { return orderService.getOrder(); } } 說明:在 user-service 使用 FeignClient 呼叫 order-service 的 getOrder 服務
- application.yml 配置檔案如下:
spring: application: name: user-service sleuth: web: client: enabled: true sampler: probability: 1.0 zipkin: base-url: http://192.168.10.100:9411/ enabled: true sender: type: RABBIT rabbitmq: addresses: 192.168.10.100 port: 15672 username: admin password: 12345 virtual-host: sleuth server: port: 9100 zipkin 引數說明: probability: 1.0 #將取樣比例設定為 1.0,也就是全部都需要。預設是 0.1 base-url: http://192.168.10.100:9411/ #Zipkin 伺服器的地址
- order-service
- pom依賴檔案和user-service相同
- 新建@RestController 介面 OrderController,程式碼如下:
@RestController public class OrderController { @Value("${server.port}") private String port; @RequestMapping(value = "/getOrder", method = RequestMethod.GET) public String getOrder() { return "Success, Order-Service, Port :" + port; } } 說明:getOrder介面就是給 user-service 呼叫的
- application.yml 配置檔案和user-service相同
- zuul-gateway閘道器
- 以下是pom依賴檔案
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</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-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <!--資料傳輸--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rabbit</artifactId> </dependency>
- application.yml 配置檔案如下:
spring: application: name: zuul-gateway sleuth: web: client: enabled: true sampler: probability: 1.0 zipkin: base-url: http://192.168.10.100:9411/ enabled: true sender: type: RABBIT rabbitmq: addresses: 192.168.10.100 port: 15672 username: admin password: 12345 virtual-host: sleuth server: port: 9310 eureka: client: service-url: defaultZone: http://localhost:8080/eureka/ zuul: prefix: /v1 routes: # http://localhost:9310/v1/user/ # user Api user-api: path: /user/** serviceId: user-service # order Api order-api: path: /order/** serviceId: order-service
- zipkin配置和user-service相同
- zuul 路由配置自己找資料參考啊,這裡不做說明
- 以上我們微服務全部完成,然後全部啟動
- 三,啟動各系統和元件
- 前面說不推薦使用者自己建立 Zipkin服務,那怎麼把資料傳輸到 Zipkin伺服器呢?就是利用Zipkin的環境變數,通過環境變數讓 Zipkin 從 RabbitMQ 中讀取資訊
- 1,啟動Zipkin服務,並指定 RabbitMQ做資料傳輸,Elasticsearch持久化資料,啟動命令如下:
java -jar zipkin.jar --RABBIT_URI=amqp://admin:12345@localhost:5672/sleuth --STORAGE_TYPE=elasticsearch --ES_HOSTS=http//:localhost:9200 --ES_HTTP_LOGGING=BASIC
- 說明:
--RABBIT_URI=amqp://admin:12345@localhost:5672/sleuth 指定用 RabbitMQ 做資料傳輸
--STORAGE_TYPE=elasticsearch --ES_HOSTS=http//:localhost:9200 --ES_HTTP_LOGGING=BASIC 指定用 Eelasticsearch 做資料傳輸
可配置的環境變數,請參考:https://www.rabbitmq.com/uri-spec.html
當然你覺得 搭建Elasticsearch太麻煩了,也可以用MYSQL 生成環境推薦使用 Elasticsearch,或者你只想自己試一下,那你可以不用儲存,資料就在記憶體中。
2,啟動RabbitMQ服務 http://192.168.10.100:15672/ 檢視啟動生個,推薦自己新建個使用者,然後登入 檢視。
3,啟動Elasticsearch服務,http://192.168.10.100:9200/ 檢視ES啟動,注意Elasticsearch 不能用root使用者啟動,具體怎麼操作請百度教程。
4,啟動Elasticsearch-head,http://192.168.10.100:9100/ 可以看到介面,注意 叢集健康值,要是未連線就是有問題,自己解決。
5,啟動user-service,order-service,zuul-gateway 閘道器,請求你自己定義的介面,這個有錯自己解決
檢視RabbitMQ視覺化介面,就能看到 資料傳輸資訊。如下圖:
檢視Zipkin視覺化介面,就能看到服務呼叫鏈路資訊。如下圖:
檢視Elasticsearch-head視覺化介面,就能看到 Elasticsearch 儲存的資料資訊。如下圖:
以上一個完成的分散式服務鏈路追蹤系統完成。