前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zipkin:打造自己的链路跟踪系统(一)

zipkin:打造自己的链路跟踪系统(一)

原创
作者头像
不会飞的小鸟
修改2020-03-30 11:17:12
5K0
修改2020-03-30 11:17:12
举报
文章被收录于专栏:只为你下只为你下

在微服务盛行的时代,一个公司的应用数量动辄成百上千个。应用之间的依赖关系错综复杂,定位问题、排查问题是一件令人头疼的事情。 为了解决这个问题,Google的Dapper论文应运而生。Twitter基于该论文打造了自己的链路跟踪系统(也就是本文章的主角):zipkin并将其开源

简介

Zipkin is a distributed tracing system. It helps gather timing data needed to troubleshoot latency problems in service architectures. Features include both the collection and lookup of this data. Zipkin是一个分布式追踪系统。它有助于收集解决服务架构中的延迟问题所需的计时数据。功能包括收集和查找此数据。

简单的介绍一下zipkin,详细的介绍请移步:zipkin官网

架构

zipkin架构
zipkin架构
  • reporter:上报链路数据的模块,配置在具体的应用中
  • transport:传输链路数据的模块,通常为http、Kafka
  • collector:收集&消费链路数据的模块,默认通过http收集,可以配置为Kafka消费
  • storage:存储链路数据的模块,具体实例可以为ES、Cassandra或者mysql

链路数据模型

代码语言:javascript
复制
[
    {
        "traceId":"5982fe77008310cc80f1da5e10147517",
        "name":"get",
        "id":"bd7a977555f6b982",
        "timestamp":1458702548467000,
        "duration":386000,
        "localEndpoint":{
            "serviceName":"zipkin-query",
            "ipv4":"192.168.1.2",
            "port":9411
        },
        "annotations":[
            {
                "timestamp":1458702548467000,
                "value":"sr"
            },
            {
                "timestamp":1458702548853000,
                "value":"ss"
            }
        ]
    }
]

其它更多有关于zipkin的信息请移步:

  • zipkin官网
  • zipkin github

为什么要选zipkin

业界还有其它开源的链路跟踪系统,为什么要选择zipkin?

首先列举自己的核心诉求:

  1. 性能影响小:能够容忍轻微的性能损失
  2. 多语言支持:Java、Node、Go等
  3. 插件可扩展:可以定制化开发链路跟踪插件
  4. 社区支持力度大:自己不需要过多的开发链路插件
  5. 接入成本小

业界开源的主流链路跟踪系统:

  1. skywalking
  2. pinpoint
  3. zipkin
  4. jaeger

主要对比skywalking和zipkin

skywalking

zipkin

内部实现方式

javaagent,字节码增强

aop插件

语言支持

多语言

多语言

性能

插件扩展

困难

容易

接入成本

低,开发无感知

低,开发需要配置

社区支持

可以看到

  • skywalking相较于zipkin的优势在于接入成本低、性能稍好
  • zipkin相较于skywalking的优势在于插件扩展容易

我们最终选择的是zipkin

zipkin和brave

首先说明一下zipkin和brave的关系:

  1. 从开头的架构图中可以看到:zipkin是服务端,用于查询分析、收集和持久化链路数据
  2. brave则是zipkin官方出品的Java语言的链路数据采集插件。同理还有js、go版本的采集插件

搭建zipkin服务器

在官方的demo中提供了docker镜像启动和jar包启动,但如果要做个性化开发的话必须通过自建项目然后引入zipkin server依赖进行启动。 前面两种启动方式官网都有详细的教程,这里就不介绍了。下面主要介绍一下自建项目引入zipkin server依赖启动的方式。

创建SpringBoot项目

创建好SpringBoot项目后,引入zipkin server相关jar包:

代码语言:javascript
复制
		<!-- zipkin 核心依赖 -->
        <dependency>
            <groupid>io.zipkin.java</groupid>
            <artifactid>zipkin-server</artifactid>
            <version>${zipkin-server.version}</version>
        </dependency>
        <!-- ui界面 可选 -->
        <dependency>
            <groupid>io.zipkin.java</groupid>
            <artifactid>zipkin-autoconfigure-ui</artifactid>
            <version>${zipkin-server.version}</version>
        </dependency>

        <!-- es存储 可选 -->
        <dependency>
            <groupid>io.zipkin.java</groupid>
            <artifactid>zipkin-autoconfigure-storage-elasticsearch</artifactid>
            <version>${zipkin-server.version}</version>
        </dependency>
        <!-- kafka collector 可选 -->
        <dependency>
            <groupid>io.zipkin.java</groupid>
            <artifactid>zipkin-autoconfigure-collector-kafka</artifactid>
            <version>${zipkin-server.version}</version>
        </dependency>

配置kafka和es地址:

代码语言:javascript
复制
zipkin.collector.kafka.bootstrap-servers=
zipkin.collector.kafka.topic=
zipkin.collector.kafka.groupId=

zipkin.storage.type=elasticsearch
zipkin.storage.elasticsearch.hosts=

添加@EnableZipkinServer注解

最后在SpringBoot启动类上配置@EnableZipkinServer注解

代码语言:javascript
复制
@EnableZipkinServer
@SpringBootApplication
public class ServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServerApplication.class, args);
    }
}

至此,一个可运行的zipkin服务器就搭建完成了;定制化开发:报警、性能分析下篇博客再介绍。下面介绍一下brave的使用;

brave的使用

使用brave所需要的maven依赖附在文章末尾

官方提供的brave插件列表非常多,基本上涵盖了日常用到的链路:http、rpc、db等。这是官方支持的中间件插件:

支持的插件
支持的插件

把Http API请求接入链路跟踪

下面以将Http API接入链路跟踪为例,介绍需要配置的地方:官方demo

代码语言:javascript
复制
/**
 * This adds tracing configuration to any web mvc controllers or rest template clients.
 */
@Configuration
// Importing a class is effectively the same as declaring bean methods
@Import(SpanCustomizingAsyncHandlerInterceptor.class)
public class TracingConfiguration extends WebMvcConfigurerAdapter {

  /** 
  * Configuration for how to send spans to Zipkin
  * 配置如何发送到zipkin服务器,这里使用http的方式发送
  */
  @Bean Sender sender() {
    return OkHttpSender.create("http://127.0.0.1:9411/api/v2/spans");
  }

  /** 
  * Configuration for how to buffer spans into messages for Zipkin
  * 配置reporter,何时发送到zipkin。触发方式:定时、size大小等 
  * */
  @Bean AsyncReporter<span> spanReporter() {
    return AsyncReporter.create(sender());
  }

  /** 
  * Controls aspects of tracing such as the service name that shows up in the UI 
  * 发送到zipkin的服务名,同一个应用的多个实例服务名应该相同
  */
  @Bean Tracing tracing(@Value("${spring.application.name}") String serviceName) {
    return Tracing.newBuilder()
        .localServiceName(serviceName)
        .propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
        .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
            // puts trace IDs into logs
            // 可以通过MDC.get("traceId")的方式拿到链路ID
            .addScopeDecorator(MDCScopeDecorator.create()) 
            .build()
        )
        .spanReporter(spanReporter()).build();
  }

  /** 
  * Allows someone to add tags to a span if a trace is in progress
  * 允许添加自定义tag到链路中
  *  */
  @Bean SpanCustomizer spanCustomizer(Tracing tracing) {
    return CurrentSpanCustomizer.create(tracing);
  }

  /** Decides how to name and tag spans. By default they are named the same as the http method */
  @Bean HttpTracing httpTracing(Tracing tracing) www.motianydl.cn {
    return HttpTracing.create(tracing);
  }

  /** 
  * Creates server spans for http requests 
  * 为http请求自动创建链路或者span
  * */
  @Bean Filter tracingFilter(HttpTracing httpTracing) {
    return TracingFilter.create(httpTracing);
  }

/** 
* 为RestTemplate发起的请求自动创建zipkin的链路信息
* */
  @Bean RestTemplateCustomizer useTracedHttpClient(HttpTracing httpTracing) {
    final CloseableHttpClient httpClient = TracingHttpClientBuilder.create(httpTracing).build();
    return new RestTemplateCustomizer(www.chuancenpt.com) {
      @Override public void customize(RestTemplate restTemplate) {
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
      }
    };
  }

  @Autowired SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer;

  /** Decorates server spans with application-defined web tags */
  @Override public void www.51kunlunyule.com addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(webMvcTracingCustomizer);
  }
}

上面的代码的核心配置为:

  1. sender:发送到zipkin服务器的方式:http或者kafka
  2. reporter:reporter决定何时将本地的链路数据发送到zipkin server
  3. tracing:非常重要,所有的链路跟踪组件都依赖它。包括自己开发的链路跟踪组件
  4. httpTracing、filter:为http请求添加链路信息

把dubbo rpc请求接入链路跟踪

因为上一个步骤已经把brave核心的配置都已经陪好了,所以把dubbo链路加入到链路跟踪就非常简单了,两个步骤:

首先引入brave dubbo相关依赖:

代码语言:javascript
复制
        <!--  dubbo插件      -->
        <dependency>
            <groupid>io.zipkin.brave</groupid>
            <artifactid>brave-instrumentation-dubbo-rpc</artifactid>
        </dependency>

然后再将brave dubbo filter添加到dubbo的filter链中:

  • 方法1:在application.properties文件中添加两行配置:
代码语言:javascript
复制
dubbo.consumer.filter=tracing
dubbo.provider.filter=tracing
  • 方法2:在dubbo xml配置文件中添加配置
代码语言:javascript
复制
<dubbo:consumer filter="tracing" www.luqintang.com />
<dubbo:provider filter="tracing"shentuylzc.cn />

对,就这么简单!

把mysql操作添加到链路跟踪

数据库操作这一环在整个请求链路中是非常重要的,很多问题都是因为数据库sql执行超时引起的。所以非常有必要把数据库操作给监控起来,具体的配置参考官方就行:

代码语言:javascript
复制
/**
 * A MySQL exception interceptor that will annotate spans with SQL error codes.
 *
 * <p>To use it, both TracingQueryInterceptor and TracingExceptionInterceptor must be added by
 * appending <code>?queryInterceptors=brave.mysql8.TracingQueryInterceptor&amp;exceptionInterceptors=brave.mysql8.TracingExceptionInterceptor</code>.
 */

其它的链路

其它的链路接入的方法类似,参考官方文档即可,这里就不展开介绍了。

其它

zipkin系列的文章

  1. 为阿里云ons/RocketMQ添加链路跟踪
  2. zipkin server个性化开发:统计报表功能、报警服务

zipkin相关的网站

  • zipkin官网
  • zipkin github
  • brave github

使用到的brave依赖

代码语言:javascript
复制
		<!--  核心依赖 -->
        <dependency>
            <groupid>io.zipkin.brave</groupid>
            <artifactid>brave</artifactid>
        </dependency>

        <!--   reporter      www.shentuylgw.cn-->
        <dependency>
            <groupid>io.zipkin.reporter2</groupid>
            <artifactid>zipkin-sender-okhttp3</artifactid>
        </dependency>


        <dependency>
            <groupid>io.zipkin.reporter2</groupid>
            <artifactid>zipkin-sender-kafka</artifactid>
        </dependency>


        <!--  日志依赖      -->
        <!-- Integrates so you can use log patterns like %X{traceId}/%X{spanId} -->
        <dependency>
            <groupid>io.zipkin.brave</groupid>
            <artifactid>brave-context-slf4j</artifactid>
        </dependency>

        <!-- spring mvc项目支持 -www.lecaixuanzc.cn->
        <dependency>
            <groupid>io.zipkin.brave</groupid>
            <artifactid>brave-spring-beans</artifactid>
        </dependency>


        <!--  mvc插件      -->
        <!-- Adds the MVC class and method names www.baihuayl7.cn  server spans -->
        <dependency>
            <groupid>io.zipkin.brave</groupid>
            <artifactid>brave-instrumentation-spring-webmvc</artifactid>
        </dependency>

        <!--  httpclient插件     www.chenghylpt.com  -->
        <!-- Instruments the underlying HttpClient requests that call the backend -->
        <dependency>
            <groupid>io.zipkin.brave</groupid>
            <artifactid>brave-instrumentation-httpclient</artifactid>
        </dependency>

        <!--  dubbo插件      www.maidongylgw.cn-->
        <dependency>
            <groupid>io.zipkin.brave</groupid>
            <artifactid>brave-instrumentation-dubbo-rpc</artifactid>
        </dependency>

        <!--  mysql插件     www.javachenglei.com -->
        <dependency>
            <groupid>io.zipkin.brave</groupid>
            <artifactid>brave-instrumentation-mysql8<www.yongshiyule178.com /artifactid>
        </dependency>

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
    • 架构
      • 链路数据模型
      • 为什么要选zipkin
      • zipkin和brave
        • 搭建zipkin服务器
          • 创建SpringBoot项目
          • 配置kafka和es地址:
          • 添加@EnableZipkinServer注解
        • brave的使用
          • 把Http API请求接入链路跟踪
          • 把dubbo rpc请求接入链路跟踪
          • 把mysql操作添加到链路跟踪
          • 其它的链路
      • 其它
        • zipkin系列的文章
          • zipkin相关的网站
            • 使用到的brave依赖
            相关产品与服务
            Elasticsearch Service
            腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档