原理分析dubbo分佈式應用中使用zipkin作鏈路追蹤

zipkin是什麼

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

爲何使用Zipkin

隨着業務愈來愈複雜,系統也隨之進行各類拆分,特別是隨着微服務架構和容器技術的興起,看似簡單的一個應用,後臺可能有幾十個甚至幾百個服務在支撐;一個前端的請求可能須要屢次的服務調用最後才能完成;當請求變慢或者不可用時,咱們沒法得知是哪一個後臺服務引發的,這時就須要解決如何快速定位服務故障點,Zipkin分佈式跟蹤系統就能很好的解決這樣的問題。java

zipkin架構

zipkin

如圖所示,Zipkin 主要由四部分構成:收集器、數據存儲、查詢以及 Web 界面。Zipkin 的收集器負責將各系統報告過來的追蹤數據進行接收;而數據存儲默認使用 Cassandra,也能夠替換爲 MySQL;查詢服務用來向其餘服務提供數據查詢的能力,而 Web 服務是官方默認提供的一個圖形用戶界面。mysql

而各個異構的系統服務向 Zipkin 報告數據的架構以下圖。git

異構

能夠看出,各個系統均可以向zipkin發送trace信息。github

Brave

Brave 是用來裝備 Java 程序的類庫,提供了面向 Standard Servlet、Spring MVC、Http Client、JAX RS、Jersey、Resteasy 和 MySQL 等接口的裝備能力,能夠經過編寫簡單的配置和代碼,讓基於這些框架構建的應用能夠向 Zipkin 報告數據。同時 Brave 也提供了很是簡單且標準化的接口,在以上封裝沒法知足要求的時候能夠方便擴展與定製。web

以下圖是Brave的結構圖。Brave利用reporter向zipkin的Collector發送trace信息。spring

Brave

Zipkin在dubbo中的使用

dubbo做爲一個rpc框架普遍應用於分佈式應用中,隨着業務的愈來愈複雜,一次請求的調用鏈也會變得繁雜,如何清晰的展現一次請求的調用鏈?結合Zipkin,能夠方便的展現dubbo服務調用關係鏈。sql

下面經過一個實際的例子展現dubbo應用如何使用zipkin追蹤請求的調用鏈。Brave使用起來不是很方便,編碼量有些大,而利用Spring Cloud的sleuth組件能夠很方便地使用brave,將trace數據經過http,Kafka或rabbitmq發送給zipkin。因此在本例中將採用將trace數據經過kafka發給zipkin。docker

爲了快速搭建zipkin的環境,本例採用docker的形式搭建zipkin和kafka。bootstrap

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

相關文章
相關標籤/搜索