原理分析dubbo分布式應用中使用zipkin做鏈路追蹤


zipkin是什么

Zipkin是一款開源的分布式實時數據追蹤系統(Distributed Tracking System),基於 Google Dapper的論文設計而來,由 Twitter 公司開發貢獻。其主要功能是聚集來自各個異構系統的實時監控數據。分布式跟蹤系統還有其他比較成熟的實現,例如:Naver的Pinpoint、Apache的HTrace、阿里的鷹眼Tracing、京東的Hydra、新浪的Watchman,美團點評的CAT,skywalking等。

為什么使用Zipkin

隨着業務越來越復雜,系統也隨之進行各種拆分,特別是隨着微服務架構和容器技術的興起,看似簡單的一個應用,后台可能有幾十個甚至幾百個服務在支撐;一個前端的請求可能需要多次的服務調用最后才能完成;當請求變慢或者不可用時,我們無法得知是哪個后台服務引起的,這時就需要解決如何快速定位服務故障點,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信息。

Brave

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,可以看到如下頁面。

zipkin

搭建一個dubbo分布式應用

首先搭建一個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的操作。

spring-cloud-starter-zipkin

在zipkin的brave倉庫中,zipkin對各個接入端做了集成的封裝。方便各個接入端快速接入。如下圖:

brave-instrumentation

地址: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信息。

springmvczipkin

下面講解brave-instrumentation的spring mvc 如何將springmvc訪問接入到zipkin中的。

image-20181224215647495

TraceWebServletAutoConfiguration 會在spring boot項目啟動的時候,自動加載,通過FilterRegistrationBean將TracingFilter過濾器注入到容器中。這樣每次請求都會過TracingFileter過濾器。

image-20181224220313262

在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。點擊調用鏈,顯示調用詳情。

image-20181224223351892

dubbo接入zipkin原理:

dubbo提供了spi擴展機制,繼承dubbo的Filter。即可在dubbo調用方法之前執行一些操作。類似java web的filter機制。

brave-instrumentation-dubbo-rpc中提供了一個brave.dubbo.rpc.TracingFilter,在並配置了filter。(關於dubbo的spi機制在這了不做詳細的解釋)

filter配置

在配置文件的dubbo節點下面配置

dubbo:
  consumer:
    filter: 'tracing'
  provider:
    filter: 'tracing'

當請求到達消費端和服務提供端的時候都會向zipkin發送trace信息。

總結

本文從以下幾點講解了dubbo分布式應用中如何做zipkin鏈路追蹤。

  1. zipkin介紹
  2. zipkin環境搭建
  3. zipkin在spring mvc的中使用與基本原理
  4. zipkin在dubbo中的使用以及基本原理

源代碼:https://github.com/applenele/zipkin-dubbo-demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM