Twitter的zipkin是一个致力于收集Twitter所有的分布式服务的时间数据的分布式跟踪系统。它提供了收集数据,和查询数据两大服务。系统的理论模型来自于Google Dapper 论文。Dapper这篇论文可以点击这里。
一般来说,分布式跟踪系统由以下组件构成。
跟踪的信息是通过封装好的框架,部署在每台机器上面,然后发送到zipkin。当主机对某一个服务发起请求时,请求所经过的路径都会被跟踪记录下来,并且最终会在zipkin 的服务器端把这些调用链组装起来。
Twitter对一些的基础框架作了封装,以便于对请求做拦截,并且在拦截的同时,还会把 Trace header 传递到下一层。
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")
Trace.recordBinary("http.response.code", "500")
Ruby Thrift
Ruby thrift 是对ruby语言的支持。
Querulous
Querulous 是一个Scala的访问数据的框架,可以理解为Java中的hibernate,用它就可以跟踪所有的sql访问情况。
Cassie是一个基于Finagle的Cassandra客户端。可以和Finagle一样设置跟踪功能。
KeyspaceBuilder.cluster.keyspace(keyspace).tracer(ZipkinTracer.mk())
Twitter使用scirbe来把所有的跟踪数据传输到zipkin的后端和hadoop文件系统。scribe是facebook开发的,运行在每台机器上面。
Zipkin collector 进程
一旦搜集的数据到达zipkin的后端,服务器端会对数据进行校验、存储,索引。
数据最开始是放在cassandra数据库中,当然zipkin在存储这块,做到可插播,目前已经做到支持redis,Hbase,MySQL,PostgreSQL, SQLite, and H2。
当数据被索引和存储之后,zipkin还提供一个查询进程用于获取数据。查询接口也是基于Thrift协议来实现了,做到了与语言无关性。
zipkin的数据可视化是通过一个叫做D3的js库来实现的。
在Twitter,zipkin已经被集成到一些基础的框架和类库之中,对于开发者来说,如果想要封装其他的框架,就需要对跟踪的数据模型有一个清晰的认识:
另外,还需要把一些轻量级的TraceID和Span ID在服务之间传递,这样才能形成一个完整的调用链。
跟踪的头信息包括以下:
以HTTP协议为例子,具体的封装步骤如下:
检查http header中是否存在Trace header信息,如果存在就把这些信息取出来,然后存入到ThreadLocal中,进而把请求串接起来;
如果不存在,那么就开始一个新的Trace
客户端需要把Trace header的信息放在ThreadLocal中,
如果需要进行RPC调用,需要把Trace header的信息放在协议中,例如http header。
Twitter zipkin githup 地址 https://github.com/twitter/zipkin