博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Twitter zipkin 分布式跟踪系统的设计与实现
阅读量:7119 次
发布时间:2019-06-28

本文共 2463 字,大约阅读时间需要 8 分钟。

hot3.png

概述

Twitter的zipkin是一个致力于收集Twitter所有的分布式服务的时间数据的分布式跟踪系统。它提供了收集数据,和查询数据两大服务。系统的理论模型来自于Google Dapper 论文。。

为什么需要分布式跟踪系统?

通过采集跟踪数据可以帮助开发者深入了解在分布式系统中某一个特定的请求时如何执行的。假如说,我们现在有一个用户请求超时,我们就可以将这个超时的请求调用链展示在UI当中。我们可以很快度的定位到导致响应很慢的服务究竟是什么。如果对这个服务细节也很很清晰,那么我们还可以定位是服务中的哪个问题导致超时。

架构

一般来说,分布式跟踪系统由以下组件构成。

封装基础框架

跟踪的信息是通过封装好的框架,部署在每台机器上面,然后发送到zipkin。当主机对某一个服务发起请求时,请求所经过的路径都会被跟踪记录下来,并且最终会在zipkin 的服务器端把这些调用链组装起来。Twitter对一些的基础框架作了封装,以便于对请求做拦截,并且在拦截的同时,还会把 Trace header 传递到下一层。

Finagle

Finagle 是Twitter的 SOA 框架,支持Java/Scala两种语言。

Finagle 在Twitter被广泛使用,通过finagle来支持跟踪是一个非常自然的入口点。目前twitter可以使它支持客户端/服务端的Thrift协议和HTTP协议,对于Memecache和Redis仅能做到客户端支持。使用Scala语言来建立一个 Finagle Server,非常简单,如下。想要加入跟踪功能,只需要把tracer 作为参数传入,构建即可。

ServerBuilder().codec(ThriftServerFramedCodec())                       .bindTo(serverAddr)                       .name("servicename")                       .tracer(ZipkinTracer.mk())                       .build(new SomeService.FinagledService(queryService, new TBinaryProtocol.Factory()))

 

跟踪客户端也是类似的。一旦这样做了之后,请求就会被自动记录下来。包括客户端请求的开始和结束、服务端的开始和结束。

如果你想记录一些自定义的内容,zipkin还提供了如下的API:记录 timestamp / value

 

Trace.record("starting that extremely expensive computation")

记录key/value

 

Trace.recordBinary("http.response.code", "500")

Ruby Thrift

Ruby thrift 是对ruby语言的支持。

Querulous

 是一个Scala的访问数据的框架,可以理解为Java中的hibernate,用它就可以跟踪所有的sql访问情况。

Cassie

Cassie是一个基于Finagle的Cassandra客户端。可以和Finagle一样设置跟踪功能。

 

KeyspaceBuilder.cluster.keyspace(keyspace).tracer(ZipkinTracer.mk())

 

 

传输

Twitter使用scirbe来把所有的跟踪数据传输到zipkin的后端和hadoop文件系统。scribe是facebook开发的,运行在每台机器上面。

Zipkin collector 进程

一旦搜集的数据到达zipkin的后端,服务器端会对数据进行校验、存储,索引。

Storage

数据最开始是放在cassandra数据库中,当然zipkin在存储这块,做到可插播,目前已经做到支持redis,Hbase,MySQL,PostgreSQL, SQLite, and H2。

Zipkin query 进程

当数据被索引和存储之后,zipkin还提供一个查询进程用于获取数据。查询接口也是基于Thrift协议来实现了,做到了与语言无关性。

UI

zipkin的数据可视化是通过一个叫做D3的js库来实现的。

模块

 

怎么去封装一个框架

在Twitter,zipkin已经被集成到一些基础的框架和类库之中,对于开发者来说,如果想要封装其他的框架,就需要对跟踪的数据模型有一个清晰的认识:

  • annotation :包括一个值,时间戳,主机名
  • span :一组代表一次RPC请求所包含的annotations
  • Trace :一组代表一次用户请求所包含的spans,其中根span只有一个。

 

另外,还需要把一些轻量级的TraceID和Span ID在服务之间传递,这样才能形成一个完整的调用链。

跟踪的头信息包括以下:

  • Trace Id - 全局的 id
  • Span Id - 每个方法调用的id
  • Optional Parent Span Id - 当前方法调用的父方法的 span id
  • Sampled boolean - 是否需要采样

 

以HTTP协议为例子,具体的封装步骤如下:

服务端

  1. 检查http header中是否存在Trace header信息,如果存在就把这些信息取出来,然后存入到ThreadLocal中,进而把请求串接起来;

  2. 如果不存在,那么就开始一个新的Trace

客户端

  1. 客户端需要把Trace header的信息放在ThreadLocal中,

  2. 如果需要进行RPC调用,需要把Trace header的信息放在协议中,例如http header。

 

github 地址

 

Twitter zipkin github 地址 

 

转载于:https://my.oschina.net/ytqvip/blog/752738

你可能感兴趣的文章
charles工具过滤腾讯视频播放器广告
查看>>
mybatis3的返回结果集如何映射到对应的bean或者是map中?
查看>>
day24 Pythonpython 面向对象设计 类
查看>>
FJUT Home_W的gcd(乱搞)题解
查看>>
[爬虫] requests库
查看>>
Cap09_项目人力资源管理
查看>>
if-else选择结构
查看>>
【100题】第五十七题 用两个栈实现队列
查看>>
hdoj 2073--无限的路
查看>>
JAVAWEB项目如何实现验证码
查看>>
JAVA 从头开始<二>
查看>>
RabbitMQ安装
查看>>
翻译:Bing地图瓦片体系
查看>>
hdu3315 /最大权最佳匹配(最大权下尽量不改变次序)(有权田忌赛马类问题)/费用流...
查看>>
ABP前端使用阿里云angular2 UI框架NG-ZORRO分享
查看>>
神秘的subsys_initcall【转】
查看>>
linux RTC 驱动模型分析【转】
查看>>
EPLAN Electric P8 2.0即将到来,着实令人期待-转caodaping
查看>>
面向对象与面向过程的对比——以自动售票机程序为例
查看>>
【Alpha】Scrum Meeting 3
查看>>