zipkin是什么
Zipkin是一款開源的分布式實時數據追蹤系統(Distributed Tracking System),基於 Google Dapper的論文設計而來,由 Twitter 公司開發貢獻。其主要功能是聚集來自各個異構系統的實時監控數據。分布式跟蹤系統還有其他比較成熟的實現,例如:Naver的Pinpoint、Apache的HTrace、阿里的鷹眼Tracing、京東的Hydra、新浪的Watchman,美團點評的CAT,skywalking等。
為什么使用Zipkin
隨着業務越來越復雜,系統也隨之進行各種拆分,特別是隨着微服務架構和容器技術的興起,看似簡單的一個應用,后台可能有幾十個甚至幾百個服務在支撐;一個前端的請求可能需要多次的服務調用最后才能完成;當請求變慢或者不可用時,我們無法得知是哪個后台服務引起的,這時就需要解決如何快速定位服務故障點,Zipkin分布式跟蹤系統就能很好的解決這樣的問題。
zipkin架構
如圖所示,Zipkin 主要由四部分構成:收集器、數據存儲、查詢以及 Web 界面。Zipkin 的收集器負責將各系統報告過來的追蹤數據進行接收;而數據存儲默認使用 Cassandra,也可以替換為 MySQL;查詢服務用來向其他服務提供數據查詢的能力,而 Web 服務是官方默認提供的一個圖形用戶界面。
而各個異構的系統服務向 Zipkin 報告數據的架構如下圖。
可以看出,各個系統都可以向zipkin發送trace信息。
Brave
Brave 是用來裝備 Java 程序的類庫,提供了面向 Standard Servlet、Spring MVC、Http Client、JAX RS、Jersey、Resteasy 和 MySQL 等接口的裝備能力,可以通過編寫簡單的配置和代碼,讓基於這些框架構建的應用可以向 Zipkin 報告數據。同時 Brave 也提供了非常簡單且標准化的接口,在以上封裝無法滿足要求的時候可以方便擴展與定制。
如下圖是Brave的結構圖。Brave利用reporter向zipkin的Collector發送trace信息。
Zipkin在dubbo中的使用
dubbo作為一個rpc框架廣泛應用於分布式應用中,隨着業務的越來越復雜,一次請求的調用鏈也會變得繁雜,如何清晰的展示一次請求的調用鏈?結合Zipkin,可以方便的展示dubbo服務調用關系鏈。
下面通過一個實際的例子展示dubbo應用如何使用zipkin追蹤請求的調用鏈。Brave使用起來不是很方便,編碼量有些大,而利用Spring Cloud的sleuth組件可以很方便地使用brave,將trace數據通過http,Kafka或rabbitmq發送給zipkin。所以在本例中將采用將trace數據通過kafka發給zipkin。
為了快速搭建zipkin的環境,本例采用docker的形式搭建zipkin和kafka。
zipkin 環境搭建
docker-compose.yml 內容如下:
version: '2'
services:
storage:
image: openzipkin/zipkin-mysql
container_name: mysql
ports:
- 3306:3306
## kafka
kafka-zookeeper:
image: openzipkin/zipkin-kafka
container_name: kafka-zookeeper
ports:
- 2181:2181
- 9092:9092
zipkin:
image: openzipkin/zipkin
container_name: zipkin
environment:
- STORAGE_TYPE=mysql
- MYSQL_HOST=mysql
- KAFKA_BOOTSTRAP_SERVERS=kafka-zookeeper:9092
ports:
- 9411:9411
depends_on:
- storage
- kafka-zookeeper
dependencies:
image: openzipkin/zipkin-dependencies
container_name: dependencies
entrypoint: crond -f
environment:
- STORAGE_TYPE=mysql
- MYSQL_HOST=mysql
- MYSQL_USER=zipkin
- MYSQL_PASS=zipkin
depends_on:
- storage
如上所示,本例將采用mysql作為zipkin的存儲,也可替換成別的存儲如:es等等。
啟動上面的docker-compose文件。啟動完成。可以訪問路徑localhost:9411,可以看到如下頁面。
搭建一個dubbo分布式應用
首先搭建一個dubbo的項目。
service-order 依賴 service-user項目。當查詢訂單詳情的時候order服務會去調用user模塊獲取用戶詳情。service-user-dubbo-api是user服務定義模塊。
spring mvc 接入zipkin
在service-order和service-user中添加maven引用。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
spring-cloud-starter-zipkin 封裝了了brave的操作。
在zipkin的brave倉庫中,zipkin對各個接入端做了集成的封裝。方便各個接入端快速接入。如下圖:
地址:https://github.com/openzipkin/brave/tree/master/instrumentation
在service-order和service-user添加相關配置:(只列出service-user,service-order類似)
dubbo:
protocol:
port: 20881
name: dubbo
id: dubbo
application:
name: service-user
registry:
protocol: zookeeper
address: localhost:2181
scan:
base-packages: com.lenny.sample.user.service
spring:
# 啟用sleuth
sleuth:
enabled: true
sampler:
probability: 1
zipkin:
sender:
type: kafka #向kafka發送trace信息
#kafka配置
kafka:
bootstrap-servers: PLAINTEXT://localhost:19092
application:
name: service-user
此時訪問service-order的獲取訂單詳情的接口 http://localhost:8081/order/1,此時在zipkin中會出現一條trcace記錄。和清楚地看出是訪問/order/1產生的trace信息。
下面講解brave-instrumentation的spring mvc 如何將springmvc訪問接入到zipkin中的。
TraceWebServletAutoConfiguration 會在spring boot項目啟動的時候,自動加載,通過FilterRegistrationBean將TracingFilter過濾器注入到容器中。這樣每次請求都會過TracingFileter過濾器。
在doFilter的時候將訪問信息發送給zipkin。 詳細代碼不做解釋了。
dubbo 接入到zipkin
上面的訪問訂單詳情的接口通過dubbo訪問了user模塊的獲取用戶信息的遠程接口,但是該訪問並沒有記錄到zipkin上。想要讓dubbo的訪問記錄也發送到zipkin上,形成完整的調用鏈,該怎么做呢?
在brave-instrumentation中有個dubbo-rpc的庫,這個庫就是將dubbo訪問信息記錄zipkin的brave封裝。 spring-cloud-starter-zipkin默認並沒有引入該類庫。
首先我們引入該類庫。
在service-order和service-user模塊maven中添加如下應用:
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-dubbo-rpc</artifactId>
<version>5.6.0</version>
</dependency>
修改server-order和service-user配置文件,在dubbo節點下增加如下配置。
dubbo:
consumer:
filter: 'tracing'
provider:
filter: 'tracing'
重啟service-order和service-user,再次訪問http://localhost:8081/order/1
發現新的請求調用鏈包含service-order和servicice-user。點擊調用鏈,顯示調用詳情。
dubbo接入zipkin原理:
dubbo提供了spi擴展機制,繼承dubbo的Filter。即可在dubbo調用方法之前執行一些操作。類似java web的filter機制。
brave-instrumentation-dubbo-rpc中提供了一個brave.dubbo.rpc.TracingFilter,在並配置了filter。(關於dubbo的spi機制在這了不做詳細的解釋)
在配置文件的dubbo節點下面配置
dubbo:
consumer:
filter: 'tracing'
provider:
filter: 'tracing'
當請求到達消費端和服務提供端的時候都會向zipkin發送trace信息。
總結
本文從以下幾點講解了dubbo分布式應用中如何做zipkin鏈路追蹤。
- zipkin介紹
- zipkin環境搭建
- zipkin在spring mvc的中使用與基本原理
- zipkin在dubbo中的使用以及基本原理