服務化改造實踐(三) | Dubbo + Zipkin

摘要: 隨着業務的發展,應用的規模不斷的擴大,傳統的應用架構沒法知足訴求,服務化架構改造勢在必行,以 Dubbo 爲表明的分佈式服務框架成爲了服務化改造架構中的基石。隨着微服務理念逐漸被大衆接受,應用進一步向更細粒度拆分,而且,不一樣的應用由不一樣的開發團隊獨立負責,整個分佈式系統變得十分複雜。php

隨着業務的發展,應用的規模不斷的擴大,傳統的應用架構沒法知足訴求,服務化架構改造勢在必行,以 Dubbo 爲表明的分佈式服務框架成爲了服務化改造架構中的基石。隨着微服務理念逐漸被大衆接受,應用進一步向更細粒度拆分,而且,不一樣的應用由不一樣的開發團隊獨立負責,整個分佈式系統變得十分複雜。沒有人可以清晰及時的知道當前系統總體的依賴關係。當出現問題時,也沒法及時知道具體是鏈路上的哪一個環節出了問題。java

在這個背景下,Google 發表了 Dapper 的論文,描述瞭如何經過一個分佈式追蹤系統解決上述問題。基於該論文,各大互聯網公司實現並部署了本身的分佈式追蹤系統,其中比較出名的有阿里巴巴的 EagleEye。本文中提到的 Zipkin 是 Twitter 公司開源的分佈式追蹤系統。下面會詳細介紹如何在 Dubbo 中使用 Zipkin 來實現分佈式追蹤。git

Zipkin 簡介
Zipkin 是基於 Dapper 論文實現,由 Twitter 開源的分佈式追蹤系統,經過收集分佈式服務執行時間的信息來達到追蹤服務調用鏈路、以及分析服務執行延遲等目的。github

Zipkin 架構spring

圖片描述

Collector 收集器、Storage 存儲、API、UI 用戶界面等幾部分構成了 Zipkin Server 部分,對應於 GitHub 上 openzipkin/zipkin 這個項目。而收集應用中調用的耗時信息並將其上報的組件與應用共生,並擁有各個語言的實現版本,其中 Java 的實現是 GitHub 上 openzipkin/brave。除了 Java 客戶端實現以外,openzipkin 還提供了許多其餘語言的實現,其中包括了 go、php、JavaScript、.net、ruby 等,具體列表能夠參閱 Zipkin 的 Exiting instrumentations。apache

Zipkin 的工做過程
當用戶發起一次調用時,Zipkin 的客戶端會在入口處爲整條調用鏈路生成一個全局惟一的 trace id,併爲這條鏈路中的每一次分佈式調用生成一個 span id。span 與 span 之間能夠有父子嵌套關係,表明分佈式調用中的上下游關係。span 和 span 之間能夠是兄弟關係,表明當前調用下的兩次子調用。一個 trace 由一組 span 組成,能夠當作是由 trace 爲根節點,span 爲若干個子節點的一棵樹。編程

圖片描述

Span 由調用邊界來分隔,在 Zipkin 中,調用邊界由如下四個 annotation 來表示:api

cs - Clent Sent 客戶端發送了請求
sr - Server Receive 服務端接受到請求
ss - Server Send 服務端處理完畢,向客戶端發送迴應
cr - Client Receive 客戶端收到結果
顯然,經過這四個 annotation 上的時間戳,能夠輕易的知道一次完整的調用在不一樣階段的耗時,好比:瀏覽器

sr - cs 表明了請求在網絡上的耗時
ss - sr 表明了服務端處理請求的耗時
cr - ss 表明了迴應在網絡上的耗時
cr - cs 表明了一次調用的總體耗時
Zipkin 會將 trace 相關的信息在調用鏈路上傳遞,並在每一個調用邊界結束時異步的把當前調用的耗時信息上報給 Zipkin Server。Zipkin Server 在收到 trace 信息後,將其存儲起來,Zipkin 支持的存儲類型有 inMemory、MySql、Cassandra、以及 ElasticsSearch 幾種方式。隨後 Zipkin 的 Web UI 會經過 API 訪問的方式從存儲中將 trace 信息提取出來分析並展現,以下圖所示:ruby

圖片描述

在 Dubbo 中使用
因爲 Brave 對 Dubbo 已經主動作了支持,在 Dubbo 中集成基於 Zipkin 的鏈路追蹤變的十分簡單。下面會按照 Brave 中關於 Dubbo RPC 支持的指引來講明如何在 Dubbo 中使用 Zipkin。

安裝 Zipkin Server
按照 Zipkin 官方文檔中的快速開始 來安裝 Zipkin,以下所示:

$ curl -sSL https://zipkin.io/quickstart.sh | bash -s
$ java -jar zipkin.jar
按照這種方式安裝的 Zipkin Server 使用的存儲類型是 inMemory 的。當服務器停機以後,全部收集到的 trace 信息會丟失,不適用於生產系統。若是在生產系統中使用,須要配置另外的存儲類型。Zipkin 支持 MySql、Cassandra、和 ElasticSearch。推薦使用 Cassandra 和 ElasticSearch,相關的配置請自行查閱官方文檔。

本文爲了演示方便,使用的存儲是 inMemory 類型。成功啓動以後,能夠在終端看到以下的提示:

$ java -jar zipkin.jar
Picked up JAVA_TOOL_OPTIONS: -Djava.awt.headless=true

********
                              **        **
                             *            *
                            **            **
                            **            **
                             **          **
                              **        **
                                ********
                                  ****
                                  ****
    ****                          ****
 ******                           ****                                 ***

*******                           ****                                 ***
    ****                          ****
                                   **
                                   **


         *****      **     *****     ** **       **     **   **
           **       **     **  *     ***         **     **** **
          **        **     *****     ****        **     **  ***
         ******     **     **        **  **      **     **   **

:: Powered by Spring Boot :: (v2.0.5.RELEASE)

...

o.s.b.w.e.u.UndertowServletWebServer : Undertow started on port(s) 9411 (http) with context path ''
2018-10-10 18:40:31.605 INFO 21072 --- [ main] z.s.ZipkinServer : Started ZipkinServer in 6.835 seconds (JVM running for 8.35)
而後在瀏覽器中訪問 http://localhost:9411 驗證 WEB 界面。

配置 Maven 依賴
引入 Brave 依賴
新建一個新的 Java 工程,並在 pom.xml 中引入 Brave 相關的依賴以下:

<properties>
    <brave.version>5.4.2</brave.version>
    <zipkin-reporter.version>2.7.9</zipkin-reporter.version>
</properties>

<dependencyManagement>
    <dependencies>
        <!-- 引入 zipkin brave 的 BOM 文件 -->
        <dependency>
            <groupId>io.zipkin.brave</groupId>
            <artifactId>brave-bom</artifactId>
            <version>${brave.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        
        <!-- 引入 zipkin repoter 的 BOM 文件 -->
        <dependency>
            <groupId>io.zipkin.reporter2</groupId>
            <artifactId>zipkin-reporter-bom</artifactId>
            <version>${zipkin-reporter.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- 1. brave 對 dubbo 的集成 -->
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-instrumentation-dubbo-rpc</artifactId>
    </dependency>

    <!-- 2. brave 的 spring bean 支持 -->
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-spring-beans</artifactId>
    </dependency>

    <!-- 3. 在 SLF4J 的 MDC (Mapped Diagnostic Context) 中支持 traceId 和 spanId -->
    <dependency>
        <groupId>io.zipkin.brave</groupId>
        <artifactId>brave-context-slf4j</artifactId>
    </dependency>

    <!-- 4. 使用 okhttp3 做爲 reporter -->
    <dependency>
        <groupId>io.zipkin.reporter2</groupId>
        <artifactId>zipkin-sender-okhttp3</artifactId>
    </dependency>
</dependencies>

其中:

引入 brave-instrumentation-dubbo-rpc,brave 對 dubbo 的支持:https://github.com/openzipkin...
引入 brave-spring-beans,brave 對 spring bean 的支持:https://github.com/openzipkin...
引入 brave-context-slf4j,brave 對 SLF4J 的支持,能夠在 MDC 中使用 traceId 和 spanId:https://github.com/openzipkin...
引入 zipkin-sender-okhttp3,使用 okhttp3 上報數據:https://github.com/openzipkin...
引入 Dubbo 相關依賴
Dubbo 相關的依賴是 Dubbo 自己以及 Zookeeper 客戶端,在下面的例子中,咱們將會使用獨立的 Zookeeper Server 做爲服務發現。

<dependencies>
    <!-- 1. Zookeeper 客戶端依賴 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.12.0</version>
        <exclusions>
            <exclusion>
                <groupId>io.netty</groupId>
                <artifactId>netty</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- 2. Dubbo 依賴 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.6.2</version>
    </dependency>
</dependencies>

其中:

Dubbo 這裏依賴獨立的 Zookeeper Server 作服務發現,這裏使用的客戶端是 Curator
引入 Dubbo 框架的依賴,原則上 2.6 的任何版本都是工做的,這裏使用的是 2.6.2 版本
實現
咱們這裏構造的場景是一個有兩個節點的服務依賴鏈,也就是,當一個 Dubbo 客戶端調用服務 A 時,服務 A 將會繼續調用服務 B。在這個例子中,服務 A 是 greeting service,它所依賴的下游服務服務 B 是 hello service。

定義服務接口
爲此須要事先定義兩個服務接口 GreetingService 以及 HelloService

com.alibaba.dubbo.samples.api.GreetingService

package com.alibaba.dubbo.samples.api;

public interface GreetingService {

String greeting(String message);

}
com.alibaba.dubbo.samples.api.HelloService

package com.alibaba.dubbo.samples.api;

public interface HelloService {

String hello(String message);

}
實現服務接口
爲了區分對待,全部和 HelloService 相關的實現代碼都放在 hello 子包下,同理 GreetingService 相關的放在 greeting 子包下。

實現 com.alibaba.dubbo.samples.api.HelloService

package com.alibaba.dubbo.samples.service.hello;

import com.alibaba.dubbo.samples.api.HelloService;

import java.util.Random;

public class HelloServiceImpl implements HelloService {

@Override
public String hello(String message) {
    try {
        // 經過 sleep 模擬業務邏輯處理時間
        Thread.sleep(new Random(System.currentTimeMillis()).nextInt(1000));
    } catch (InterruptedException e) {
        // no op
    }
    return "hello, " + message;
}

}
實現 com.alibaba.dubbo.samples.api.GreetingService

package com.alibaba.dubbo.samples.service.greeting;

import com.alibaba.dubbo.samples.api.GreetingService;
import com.alibaba.dubbo.samples.api.HelloService;

import java.util.Random;

public class GreetingServiceImpl implements GreetingService {

// 下游依賴服務,運行時靠 spring 容器注入 HelloService 的服務代理
private HelloService helloService;

public void setHelloService(HelloService helloService) {
    this.helloService = helloService;
}

@Override
public String greeting(String message) {
    try {
        // 經過 sleep 模擬業務邏輯處理時間
        Thread.sleep(new Random(System.currentTimeMillis()).nextInt(1000));
    } catch (InterruptedException e) {
        // no op
    }
    return "greeting, " + helloService.hello(message);
}

}
這裏須要注意的是,GreetingServiceImpl 的實現中聲明瞭一個類型是 HelloService 的成員變量,並在 greeting 方法中,執行完本身邏輯以後又調用了 HelloService 上的 hello 方法。這裏的 helloService 的實現將會在運行態由外部注入,注入的不是 HelloServiceImpl 的實現,而是 HelloService 的遠程調用代理。經過這樣的方式,完成了在一個 Dubbo 服務中繼續調用另外一個遠程 Dubbo 服務的目的。從鏈路追蹤的角度來講,客戶端調用 GreetingService 是一個 span,GreetingService 調用 HelloService 是另外一個 span,而且二者有父子關係,同屬於一個 trace,也就是屬於同一條調用鏈路。

另外,在 GreetingServiceImpl 和 HelloServiceImpl 的實現中,經過 Thread.sleep 來模擬了處理業務邏輯的耗時,以便在 Zipkin UI 上更好的展現。

配置
爲了專一在展現如何使用 Zipkin 這一點上,本文在配置和編程模型上沒有采用更多的高級技術,而是使用了最傳統的 Spring XML 的配置方式,幫助讀者理解。更高級的經過 annotation 甚至 spring boot 的方式,讀者能夠自行查閱 Dubbo 和 Zipkin 相關的文檔。

暴露 HelloService 服務

在 resouces/spring/hello-service.xml 中增長如下的配置來將 HelloServiceImpl 暴露成一個 Dubbo 服務:

使用了本地啓動的 Zookeeper Server 做爲註冊中心,地址爲默認值 zookeeper://127.0.0.1:2181
用 Dubbo 原生服務在端口 20880 上暴露服務
將 HelloServiceImpl 註冊成 id 是 helloService 的 Spring Bean,這樣就能夠在後續的 <dubbo:service> 中引用到這個實現類
經過 <dubbo:service> 將 HelloServiceImpl 暴露成 Dubbo 服務

<!-- 定義 HelloService 的應用名 -->
<dubbo:application name="hello-service-provider"/>

<!-- 指定註冊中心地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>

<!-- 使用 Dubbo 原生協議在 20880 端口上暴露服務 -->
<dubbo:protocol name="dubbo" port="20880"/>

<!-- 將 HelloServiceImpl 的實現聲明成一個 spring bean -->
<bean id="helloService" class="com.alibaba.dubbo.samples.service.hello.HelloServiceImpl"/>

<!-- 將 HelloServiceImpl 聲明成一個 Dubbo 服務 -->
<dubbo:service interface="com.alibaba.dubbo.samples.api.HelloService" ref="helloService"/>

增長 Zipkin 相關的配置

在 resources/spring/hello-service.xml 中增長 Zipkin 相關的配置:

修改 dubbo 服務暴露的配置,添加 Zipkin 的 tracing filter 到 Dubbo 的 filter chain 中
按照 https://github.com/openzipkin... 來配置 Zipkin 的 sender 和 tracing 的 spring bean

<!-- 1. 修改 dubbo 服務暴露配置,在 filter chain 中增長 zipkin 的 tracing 過濾器 -->
<dubbo:service interface="com.alibaba.dubbo.samples.api.HelloService" ref="helloService" filter="tracing"/>

<!-- 2. zipkin 相關的配置 -->
<!-- 使用 OKHttp 來發送 trace 信息到 Zipkin Server。這裏的 Zipkin Server 啓動在本地 -->
<bean id="sender" class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
    <property name="endpoint" value="http://localhost:9411/api/v2/spans"/>
</bean>

<bean id="tracing" class="brave.spring.beans.TracingFactoryBean">
    <property name="localServiceName" value="hello-service"/>
    <property name="spanReporter">
        <bean class="zipkin2.reporter.beans.AsyncReporterFactoryBean">
            <property name="sender" ref="sender"/>
            <!-- wait up to half a second for any in-flight spans on close -->
            <property name="closeTimeout" value="500"/>
        </bean>
    </property>
    <property name="currentTraceContext">
        <bean class="brave.spring.beans.CurrentTraceContextFactoryBean">
            <property name="scopeDecorators">
                <bean class="brave.context.slf4j.MDCScopeDecorator" factory-method="create"/>
            </property>
        </bean>
    </property>
</bean>

增長 HelloService 的啓動類

在 com.alibaba.dubbo.samples.service.hello.Application 中經過 ClassPathXmlApplicationContext 讀取 剛纔配置的 spring/hello-service.xml 來初始化一個 spring context 並啓動

package com.alibaba.dubbo.samples.service.hello;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class Application {

public static void main(String[] args) throws IOException {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/hello-service.xml");
    context.start();

    System.out.println("Hello service started");
    // press any key to exit
    System.in.read();
}

}
暴露 GreetingService 服務,並使用 Zipkin

在 resources/spring/greeting-service.xml 中配置 GreetingService。相關步驟與 HelloService 相似,再也不贅述,重點關注如何在 GreetingService 中配置下游服務的依賴。完整的 XML 配置以下:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
   xmlns="http://www.springframework.org/schema/beans"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

<!-- 1. 定義 GreetingService 的應用名 -->
<dubbo:application name="greeting-service-provider"/>

<!-- 2. 指定註冊中心地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>

 <!-- 3. 使用 Dubbo 原生協議在 20881 端口上暴露服務 -->
<dubbo:protocol name="dubbo" port="20881"/>

<!-- 4. 聲明 HelloService 的遠程代理,並在 Dubbo 的 filter chain 中增長 tracing filter -->
<dubbo:reference id="helloService" check="false" interface="com.alibaba.dubbo.samples.api.HelloService" filter="tracing"/>

<!-- 5. 將 GreetingServiceImpl 的實現聲明成一個 spring bean,並將 HelloService 的遠程代理裝配進去 -->
<bean id="greetingService" class="com.alibaba.dubbo.samples.service.greeting.GreetingServiceImpl">
    <property name="helloService" ref="helloService"/>
</bean>

<!-- 6. 將 GreetingServiceImpl 聲明成一個 Dubbo 服務,並在 Dubbo 的 filter chain 中增長 tracing filter -->
<dubbo:service interface="com.alibaba.dubbo.samples.api.GreetingService" ref="greetingService" filter="tracing"/>

<!-- 7. zipkin 相關的配置 -->
<bean id="sender" class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
    <property name="endpoint" value="http://localhost:9411/api/v2/spans"/>
</bean>

<bean id="tracing" class="brave.spring.beans.TracingFactoryBean">
    <property name="localServiceName" value="greeting-service"/>
    <property name="spanReporter">
        <bean class="zipkin2.reporter.beans.AsyncReporterFactoryBean">
            <property name="sender" ref="sender"/>
            <!-- wait up to half a second for any in-flight spans on close -->
            <property name="closeTimeout" value="500"/>
        </bean>
    </property>
    <property name="currentTraceContext">
        <bean class="brave.spring.beans.CurrentTraceContextFactoryBean">
            <property name="scopeDecorators">
                <bean class="brave.context.slf4j.MDCScopeDecorator" factory-method="create"/>
            </property>
        </bean>
    </property>
</bean>

</beans>
這裏的配置與上面的 HelloService 相似,須要重點關注的有兩點:

第 3 步中注意服務須要暴露在不一樣的端口上,不然會和 HelloService 衝突,本例中選擇的是 20881 這個端口
經過第 4 步先聲明 HelloService 的遠程代理,而後在第 5 步中將其組裝給 GreetingService 來完成服務上下游依賴的聲明
增長 GreeeingService 的啓動類,與 HelloService 相似,經過 spring/greeting-service.xml 的配置來初始化一個新的 spring context 來完成。

package com.alibaba.dubbo.samples.service.greeting;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class Application {

public static void main(String[] args) throws IOException {
       ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/greeting-service.xml");
       context.start();

       System.out.println("Greeting service started");
       // press any key to exit
       System.in.read();
   }

}
實現客戶端

經過 resources/spring/client.xml 初始化一個 spring context,從其中獲取 GreetingService 的遠程代理,發起遠程調用。

package com.alibaba.dubbo.samples.client;

import com.alibaba.dubbo.samples.api.GreetingService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Application {

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/client.xml");
    context.start();
    // 獲取遠程代理併發起調用
    GreetingService greetingService = (GreetingService) context.getBean("greetingService");
    System.out.println(greetingService.greeting("world"));
}

}
resource/spring/client.xml 中的配置與 Dubbo 服務的配置相似,主要是配置遠程代理,以及配置 Zipkin

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
   xmlns="http://www.springframework.org/schema/beans"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

<!-- 1. 定義 dubbo 客戶端的應用名 -->

<dubbo:application name="dubbo-client"/>

<!-- 2. 指定註冊中心地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>

<!-- 3. 聲明 GreetingService 的遠程代理,並在 Dubbo 的 filter chain 中增長 tracing filter -->
<dubbo:reference id="greetingService" check="false" interface="com.alibaba.dubbo.samples.api.GreetingService" filter="tracing"/>

<!-- 4. zipkin 相關的配置 -->
<bean id="sender" class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
    <property name="endpoint" value="http://localhost:9411/api/v2/spans"/>
</bean>

<bean id="tracing" class="brave.spring.beans.TracingFactoryBean">
    <property name="localServiceName" value="client"/>
    <property name="spanReporter">
        <bean class="zipkin2.reporter.beans.AsyncReporterFactoryBean">
            <property name="sender" ref="sender"/>
            <!-- wait up to half a second for any in-flight spans on close -->
            <property name="closeTimeout" value="500"/>
        </bean>
    </property>
    <property name="currentTraceContext">
        <bean class="brave.spring.beans.CurrentTraceContextFactoryBean">
            <property name="scopeDecorators">
                <bean class="brave.context.slf4j.MDCScopeDecorator" factory-method="create"/>
            </property>
        </bean>
    </property>
</bean>

</beans>
完成以後的工程的目錄結構以下:

圖片描述

運行
如今讓咱們把整個鏈路運行起來,看看 Zipkin 鏈路追蹤的效果。

啓動 Zookeeper Server
執行如下命令在本地啓動一個 Zookeeper Server,若是沒有安裝,請自行從 ZooKeeper 官網 下載:

$ zkServer start
啓動 Zipkin Server
執行如下命令在本地啓動一個 Zipkin Server:

$ curl -sSL https://zipkin.io/quickstart.sh | bash -s
$ java -jar zipkin.jar
啓動 HelloService
使用下面的命令啓動 HelloService,固然也能夠直接在 IDE 中啓動:

$ mvn exec:java -Dexec.mainClass=com.alibaba.dubbo.samples.service.hello.Application
啓動成功後應該能夠在終端上看到 「Hello service started」 的字樣。

啓動 GreetingService
使用下面的命令啓動 GreetingService,固然也能夠直接在 IDE 中啓動:

$ mvn exec:java -Dexec.mainClass=com.alibaba.dubbo.samples.service.greeting.Application
啓動成功後應該能夠在終端上看到 「Greeting service started」 的字樣。

運行 Dubbo 客戶端
使用下面的命令運行 Dubbo 客戶端向 GreetingService 發起遠程調用,固然也能夠直接在 IDE 中運行:

$ mvn exec:java -Dexec.mainClass=com.alibaba.dubbo.samples.client.Application
執行成功後,客戶端會在終端上輸出 「greeting, hello, world」。

鏈路追蹤
打開瀏覽器訪問 "http://localhost:9411" 並經過 "Find Traces" 按鈕來搜索,能夠找到剛剛調用的鏈路追蹤,效果以下圖所示:

圖片描述

還能夠進一步的選擇每個 span 來查看本次調用邊界內的詳情,好比,hello-service 這個 span 的詳情以下:

圖片描述

總結
本文介紹了鏈路追蹤的基本概念以及 Zipkin 的基本用法,而後用 Dubbo 構建了一條最簡單的調用鏈路,並引入了 Zipkin 作全鏈路追蹤。因爲 Zipkin 對 Dubbo 作了很好的支持,整個集成的過程仍是十分簡單明瞭的。

Zipkin 對 Dubbo 的支持是構建在 Dubbo 的 filter 擴展機制上的,有興趣的讀者能夠經過 https://github.com/openzipkin... 瞭解其實現細節。

相關文章
相關標籤/搜索