分布式监控系统zipkin介绍
zipkin是Twitter基于google的分布式监控系统Dapper(论文)的开发源实现,zipkin用于跟踪分布式服务之间的应用数据链路,分析处理延时,帮助我们改进系统的性能和定位故障。
zipkin架构
Instrumented client和Instrumented server是分布式系统中的服务,通过装备库采集跟踪信息,装备库再调用Transport,把跟踪信息发送给zipkin。
装备库
针对不同语言,不同RPC框架,有不同的装备库实现,目前已有实现列表见此,其中Brave是zipkin官方提供的Java的装备库。
一个装备库的实现需要考虑如下情况:
- 实现语言,和需要装备的服务的语言一致
- zipkin需要的核心数据结构信息记录,包括tracerid,spanid的生成,延迟时间的计算,事件记录,tag记录等
- 服务之间跟踪信息的传递,称为植入,不同RPC接口植入的方式不一样,例如HTTP接口采用B3协议植入
植入的信息包括:Trace Id、Span Id、Parent Id、Sampled、Flags - 采样,减少跟踪导致的系统负荷
- 报告给zipkin,调用Transport将跟踪信息传给zipkin
Transport
Transport是zipkin对外提供的接口,目前有HTTP、Kafka、Scribe三种。
- HTTP:采用json格式,接口定义见https://github.com/openzipkin/zipkin-api
- Kafka:分布式发布订阅消息系统
- Scribe:Facebook的日志收集系统https://github.com/facebook/scribe
核心数据结构
v2版本:
- traceId:64位或128位,全局唯一,
- parentId:父spanid,64位,根span的parentId为空
- id:spanid,64位,tranceId内唯一
- name:方法名
- serviceName:服务名
- timestamp:自1970-1-1 00:00:00 UTC的微秒
- duration:开始span到结束span的时间,单位微秒
- annotations:记录事件,value有一些预定义的值,例如客户端发送(cs),客户端接收(cr),服务端接收(sr),服务端发送(ss)等
- tags:记录附加数据
一个Span就是记录[remoteEndpoint.serviceName]服务的[Span.name]方法的执行过程,其中的annotation记录了中间的一些事件发生时间,通过这些时间可以得到[Span.name]方法的网络传输时间,服务端执行时间,客户端响应时间等信息,从而对其进行诊断优化。多个Span通过parentId构成一个树形结构,根Span的parentId为空,描述了一次trace(tranceId标识)中多个服务之间的调用过程。
示例说明
https://github.com/zhongpan/zipkin-ice
假设service1.fun1中调用service2.fun2和service3.fun3,service2.fun2中调用service4.fun4。本次跟踪各个服务中会创建如上的span1~span7,span1为根span。span2和span4为一次RPC的客户端和服务端行为,可以共享spanid,span4不用新生成spanid,span2和span4在zipkin中会合并为1个span,span3/span5以及span6/span7类似。最终,在zipkin界面展示的树形结构为: