ZipKin入门介绍

    Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper的论文设计而来,由 Twitter 公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据。分布式跟踪系统还有其他比较成熟的实现,例如:Naver的Pinpoint、Apache的HTrace、阿里的鹰眼Tracing、京东的Hydra、新浪的Watchman,美团点评的CAT,skywalking等。

ZipKin架构

    ZipKin可以分为两部分,一部分是zipkin server,用来作为数据的采集存储、数据分析与展示;zipkin client是zipkin基于不同的语言及框架封装的一些列客户端工具,这些工具完成了追踪数据的生成与上报功能,架构如下:

ZipKin原理学习--ZipKin入门介绍_被调用者

Zipkin Server主要包括四个模块:
(1)Collector 接收或收集各应用传输的数据
(2)Storage 存储接受或收集过来的数据,当前支持Memory,MySQL,Cassandra,ElasticSearch等,默认存储在内存中。
(3)API(Query) 负责查询Storage中存储的数据,提供简单的JSON API获取数据,主要提供给web UI使用

(4)Web 提供简单的web界面

服务追踪流程如下:

┌─────────────┐ ┌───────────────────────┐  ┌─────────────┐  ┌──────────────────┐
│ User Code │ │ Trace Instrumentation │ │ Http Client │ │ Zipkin Collector │
└─────────────┘ └───────────────────────┘ └─────────────┘ └──────────────────┘
│ │ │ │
┌─────────┐
│ ──┤GET /foo ├─▶ │ ────┐ │ │
└─────────┘ │ record tags
│ │ ◀───┘ │ │
────┐
│ │ │ add trace headers │ │
◀───┘
│ │ ────┐ │ │
│ record timestamp
│ │ ◀───┘ │ │
┌─────────────────┐
│ │ ──┤GET /foo ├─▶ │ │
│X-B3-TraceId: aa │ ────┐
│ │ │X-B3-SpanId: 6b │ │ │ │
└─────────────────┘ │ invoke
│ │ │ │ request │

│ │ │ │ │
┌────────┐ ◀───┘
│ │ ◀─────┤200 OK ├─────── │ │
────┐ └────────┘
│ │ │ record duration │ │
┌────────┐ ◀───┘
│ ◀──┤200 OK ├── │ │ │
└────────┘ ┌────────────────────────────────┐
│ │ ──┤ asynchronously report span ├────▶ │
│ │
│{ │
│ "traceId": "aa", │
│ "id": "6b", │
│ "name": "get", │
│ "timestamp": 1483945573944000,│
│ "duration": 386000, │
│ "annotations": [ │
│--snip-- │
└────────────────────────────────┘

Instrumented client和server是分别使用了ZipKin Client的服务,Zipkin Client会根据配置将追踪数据发送到Zipkin  Server中进行数据存储、分析和展示。

ZipKin几个概念

    在追踪日志中,有几个基本概念spanId、traceId、parentId

    traceId:用来确定一个追踪链的16字符长度的字符串,在某个追踪链中保持不变。

    spanId:区域Id,在一个追踪链中spanId可能存在多个,每个spanId用于表明在某个服务中的身份,也是16字符长度的字符串。

    parentId:在跨服务调用者的spanId会传递给被调用者,被调用者会将调用者的spanId作为自己的parentId,然后自己再生成spanId。

    如下图:

    刚发起调用时traceId和spanId是一致,parentId不存在。

ZipKin原理学习--ZipKin入门介绍_被调用者_02

    被调用者的traceId和调用者的traceId时一致的,被调用者会产生自己的spanId,并且被调用者的parentId是调用者的spanId

ZipKin原理学习--ZipKin入门介绍_mvc_03

安装

1、下载:

​https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec​

2、运行:java -jar  zipkin-server-2.8.3-exec.jar

    

ZipKin原理学习--ZipKin入门介绍_mvc_04

3、访问:zipkin Server 运行后默认的访问地址:http://localhost:9411

ZipKin原理学习--ZipKin入门介绍_被调用者_05

4、调用链分析

    启动4个服务,调用关系如下:brave-webmvc-example服务调用brave-webmvc-example2,brave-webmvc-example2分别调用brave-webmvc-example3和brave-webmvc-example4(​​代码地址​​),链路关系如下图:

ZipKin原理学习--ZipKin入门介绍_被调用者_06

右上角JSON节目可以看到4个服务的调用数据如下图:

[
{
"traceId": "a4aa11d855699355",
"id": "a4aa11d855699355",
"name": "get /start",
"timestamp": 1526110753393795,
"duration": 3873359,
"annotations": [
{
"timestamp": 1526110753393795,
"value": "sr",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110757267154,
"value": "ss",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
}
],
"binaryAnnotations": [
{
"key": "ca",
"value": true,
"endpoint": {
"serviceName": "",
"ipv6": "::1",
"port": 64570
}
},
{
"key": "http.method",
"value": "GET",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.path",
"value": "/start",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
},
{
"key": "mvc.controller.class",
"value": "HomeController",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
},
{
"key": "mvc.controller.method",
"value": "start",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
}
]
},
{
"traceId": "a4aa11d855699355",
"id": "cf49951d471ac7c5",
"name": "get /foo",
"parentId": "a4aa11d855699355",
"timestamp": 1526110753583404,
"duration": 3650640,
"annotations": [
{
"timestamp": 1526110753583404,
"value": "cs",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110754327066,
"value": "sr",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110757234044,
"value": "cr",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110757235819,
"value": "ss",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
}
],
"binaryAnnotations": [
{
"key": "ca",
"value": true,
"endpoint": {
"serviceName": "",
"ipv4": "127.0.0.1",
"port": 64578
}
},
{
"key": "http.method",
"value": "GET",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.method",
"value": "GET",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.path",
"value": "/foo",
"endpoint": {
"serviceName": "brave-webmvc-example",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.path",
"value": "/foo",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"key": "mvc.controller.class",
"value": "HomeController",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"key": "mvc.controller.method",
"value": "foo",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
}
]
},
{
"traceId": "a4aa11d855699355",
"id": "c2c029d693ecc49b",
"name": "get /bar",
"parentId": "cf49951d471ac7c5",
"timestamp": 1526110754397322,
"duration": 1583187,
"annotations": [
{
"timestamp": 1526110754397322,
"value": "cs",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110755367168,
"value": "sr",
"endpoint": {
"serviceName": "brave-webmvc-example3",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110755810759,
"value": "ss",
"endpoint": {
"serviceName": "brave-webmvc-example3",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110755980509,
"value": "cr",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
}
],
"binaryAnnotations": [
{
"key": "ca",
"value": true,
"endpoint": {
"serviceName": "",
"ipv4": "127.0.0.1",
"port": 64583
}
},
{
"key": "http.method",
"value": "GET",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.method",
"value": "GET",
"endpoint": {
"serviceName": "brave-webmvc-example3",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.path",
"value": "/bar",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.path",
"value": "/bar",
"endpoint": {
"serviceName": "brave-webmvc-example3",
"ipv4": "192.168.1.101"
}
},
{
"key": "mvc.controller.class",
"value": "HomeController",
"endpoint": {
"serviceName": "brave-webmvc-example3",
"ipv4": "192.168.1.101"
}
},
{
"key": "mvc.controller.method",
"value": "bar",
"endpoint": {
"serviceName": "brave-webmvc-example3",
"ipv4": "192.168.1.101"
}
}
]
},
{
"traceId": "a4aa11d855699355",
"id": "e3968cec8747ce95",
"name": "get /tar",
"parentId": "cf49951d471ac7c5",
"timestamp": 1526110756017988,
"duration": 1194871,
"annotations": [
{
"timestamp": 1526110756017988,
"value": "cs",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110757081683,
"value": "sr",
"endpoint": {
"serviceName": "brave-webmvc-example4",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110757212859,
"value": "cr",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"timestamp": 1526110757222145,
"value": "ss",
"endpoint": {
"serviceName": "brave-webmvc-example4",
"ipv4": "192.168.1.101"
}
}
],
"binaryAnnotations": [
{
"key": "ca",
"value": true,
"endpoint": {
"serviceName": "",
"ipv4": "127.0.0.1",
"port": 64584
}
},
{
"key": "http.method",
"value": "GET",
"endpoint": {
"serviceName": "brave-webmvc-example4",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.method",
"value": "GET",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.path",
"value": "/tar",
"endpoint": {
"serviceName": "brave-webmvc-example4",
"ipv4": "192.168.1.101"
}
},
{
"key": "http.path",
"value": "/tar",
"endpoint": {
"serviceName": "brave-webmvc-example2",
"ipv4": "192.168.1.101"
}
},
{
"key": "mvc.controller.class",
"value": "HomeController",
"endpoint": {
"serviceName": "brave-webmvc-example4",
"ipv4": "192.168.1.101"
}
},
{
"key": "mvc.controller.method",
"value": "tar",
"endpoint": {
"serviceName": "brave-webmvc-example4",
"ipv4": "192.168.1.101"
}
}
]
}
]

 

5、zipkin client采集

 

    目前官方提供了如下客户端插件进行追踪数据的采集(https://github.com/openzipkin/brave/tree/master/instrumentation)

ZipKin原理学习--ZipKin入门介绍_数据_07

 

 

题外话:由于项目需要和本人推动,尝试,官方在 2.15 版本添加支持 ActiveMQ 支持追踪日志收集

ZipKin原理学习--ZipKin入门介绍_mvc_08