千家信息网

如何在Dubbo中使用Zipkin来实现分布式追踪

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍"如何在Dubbo中使用Zipkin来实现分布式追踪",在日常操作中,相信很多人在如何在Dubbo中使用Zipkin来实现分布式追踪问题上存在疑惑,小编查阅了各式资料,整理出简单好用的
千家信息网最后更新 2026年11月01日如何在Dubbo中使用Zipkin来实现分布式追踪

这篇文章主要介绍"如何在Dubbo中使用Zipkin来实现分布式追踪",在日常操作中,相信很多人在如何在Dubbo中使用Zipkin来实现分布式追踪问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何在Dubbo中使用Zipkin来实现分布式追踪"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Zipkin 简介

Zipkin 是基于 Dapper 论文实现,由 Twitter 开源的分布式追踪系统,通过收集分布式服务执行时间的信息来达到追踪服务调用链路、以及分析服务执行延迟等目的。

Zipkin 架构

cdn.nlark.com/lark/0/2018/png/13615/1539327563392-b01ee384-c79f-48b9-9027-4bc10a4397f7.png">

Collector 收集器、Storage 存储、API、UI 用户界面等几部分构成了 Zipkin Server 部分,对应于 GitHub 上 openzipkin/zipkin 这个项目。而收集应用中调用的耗时信息并将其上报的组件与应用共生,并拥有各个语言的实现版本,其中 Java 的实现是 GitHub 上 openzipkin/brave 。除了 Java 客户端实现之外,openzipkin 还提供了许多其他语言的实现,其中包括了 go、php、JavaScript、.net、ruby 等,具体列表可以参阅 Zipkin 的 Exiting instrumentations 。

Zipkin 的工作过程

当用户发起一次调用时,Zipkin 的客户端会在入口处为整条调用链路生成一个全局唯一的 trace id,并为这条链路中的每一次分布式调用生成一个 span id。span 与 span 之间可以有父子嵌套关系,代表分布式调用中的上下游关系。span 和 span 之间可以是兄弟关系,代表当前调用下的两次子调用。一个 trace 由一组 span 组成,可以看成是由 trace 为根节点,span 为若干个子节点的一棵树。

Span 由调用边界来分隔,在 Zipkin 中,调用边界由以下四个 annotation 来表示:

  • 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 信息提取出来分析并展示,如下图所示:

在 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.jarPicked 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 相关的依赖如下:

            5.4.2        2.7.9                                                        io.zipkin.brave                brave-bom                ${brave.version}                pom                import                                                                io.zipkin.reporter2                zipkin-reporter-bom                ${zipkin-reporter.version}                pom                import                                                        io.zipkin.brave            brave-instrumentation-dubbo-rpc                                    io.zipkin.brave            brave-spring-beans                                    io.zipkin.brave            brave-context-slf4j                                    io.zipkin.reporter2            zipkin-sender-okhttp3            

其中:

  1. 引入 brave-instrumentation-dubbo-rpc,brave 对 dubbo 的支持: https://github.com/openzipkin/brave/blob/master/instrumentation/dubbo-rpc/README.md

  2. 引入 brave-spring-beans,brave 对 spring bean 的支持: https://github.com/openzipkin/brave/blob/master/spring-beans/README.md

  3. 引入 brave-context-slf4j,brave 对 SLF4J 的支持,可以在 MDC 中使用 traceId 和 spanId: https://github.com/openzipkin/brave/blob/master/context/slf4j/README.md

  4. 引入 zipkin-sender-okhttp3,使用 okhttp3 上报数据: https://github.com/openzipkin/zipkin-reporter-java

引入 Dubbo 相关依赖

Dubbo 相关的依赖是 Dubbo 本身以及 Zookeeper 客户端,在下面的例子中,我们将会使用独立的 Zookeeper Server 作为服务发现。

                                org.apache.curator            curator-framework            2.12.0                                                io.netty                    netty                                                                com.alibaba            dubbo            2.6.2            

其中:

  1. Dubbo 这里依赖独立的 Zookeeper Server 做服务发现,这里使用的客户端是 Curator

  2. 引入 Dubbo 框架的依赖,原则上 2.6 的任何版本都是工作的,这里使用的是 2.6.2 版本

实现

我们这里构造的场景是一个有两个节点的服务依赖链,也就是,当一个 Dubbo 客户端调用服务 A 时,服务 A 将会继续调用服务 B。在这个例子中,服务 A 是 greeting service,它所依赖的下游服务服务 B 是 hello service。

定义服务接口

为此需要事先定义两个服务接口 GreetingService 以及 HelloService

  1. com.alibaba.dubbo.samples.api.GreetingService

    package com.alibaba.dubbo.samples.api;public interface GreetingService {    String greeting(String message);}
  2. com.alibaba.dubbo.samples.api.HelloService

    package com.alibaba.dubbo.samples.api;public interface HelloService {    String hello(String message);}
实现服务接口

为了区分对待,所有和 HelloService 相关的实现代码都放在 hello 子包下,同理 GreetingService 相关的放在 greeting 子包下。

  1. 实现 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;    }}
  2. 实现 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 相关的文档。

  1. 暴露 HelloService 服务

    在 resouces/spring/hello-service.xml 中增加以下的配置来将 HelloServiceImpl 暴露成一个 Dubbo 服务:

                                            
    • 使用了本地启动的 Zookeeper Server 作为注册中心,地址为默认值 zookeeper://127.0.0.1:2181

    • 用 Dubbo 原生服务在端口 20880 上暴露服务

    • 将 HelloServiceImpl 注册成 id 是 helloService 的 Spring Bean,这样就可以在后续的 中引用到这个实现类

    • 通过 将 HelloServiceImpl 暴露成 Dubbo 服务

  2. 增加 Zipkin 相关的配置

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

                                                                                                                                                                                                                                        
    • 修改 dubbo 服务暴露的配置,添加 Zipkin 的 tracing filter 到 Dubbo 的 filter chain 中

    • 按照 https://github.com/openzipkin/brave/blob/master/spring-beans/README.md 来配置 Zipkin 的 sender 和 tracing 的 spring bean

  3. 增加 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();    }}
  4. 暴露 GreetingService 服务,并使用 Zipkin

    在 resources/spring/greeting-service.xml 中配置 GreetingService。相关步骤与 HelloService 类似,不再赘述,重点关注如何在 GreetingService 中配置下游服务的依赖。完整的 XML 配置如下:

                                                                                                                                                                                                                                                                                                 

    这里的配置与上面的 HelloService 类似,需要重点关注的有两点:

    增加 GreeeingService 的启动类,与 HelloService 类似,通过 spring/greeting-service.xml 的配置来初始化一个新的 spring context 来完成。

    • 第 3 步中注意服务需要暴露在不同的端口上,否则会和 HelloService 冲突,本例中选择的是 20881 这个端口

    • 通过第 4 步先声明 HelloService 的远程代理,然后在第 5 步中将其组装给 GreetingService 来完成服务上下游依赖的声明

   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();       }   }
  1. 实现客户端

    通过 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

                                                                                                                                                                                                                                                   

完成之后的工程的目录结构如下:

运行

现在让我们把整个链路运行起来,看看 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 的详情如下:

到此,关于"如何在Dubbo中使用Zipkin来实现分布式追踪"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

服务 配置 客户 客户端 链路 分布式 信息 存储 支持 运行 代表 方式 代理 命令 类型 面的 处理 成功 时间 终端 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海挚品互联网科技有限公司 什么是科技互联网 互联网科技财经 美国互联网黑科技 互联网科技公司招聘 青岛中康互联网医疗科技有限公司 互联网之后的科技是什么 互联网时代科技改变生活 河南猎农互联网科技有限公司 玉溪互联网科技怎么选 科技类公司包括互联网吗 威龙国际互联网科技公司 黑科技 体验场景 互联网大会 广州富喜互联网络科技 城市宝互联网科技有限公司 新氧科技和美国互联网有关系吗 广东鹅鹅鹅互联网科技有限公司 艺电能源互联网科技有限公司招聘 10位科技互联网大佬 科技互联网企业在行动 百单网互联网科技有限公司怎么样 苏州互联网科技贷款公司 华中科技有哪些互联网大佬 晓花互联网科技有限公司网址 无锡工业互联网科技有限公司 互联网企业科技类企业如何做账 中天科技中国工业互联网 互联网企业和网络科技有限公司 高科技和互联网的现代国家 如何强化互联网金融科技
0