全栈工程师开发手册 (作者:栾鹏)
架构系列文章


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 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不存在。

这里写图片描述

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

这里写图片描述

window安装zipkin

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

这里写图片描述

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

这里写图片描述

4、调用链分析

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

这里写图片描述

右上角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)

这里写图片描述

k8s部署zipkin服务器端

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: zipkin
  namespace: logging
spec:
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: zipkin
    spec:
      containers:
      - name: zipkin
        image: openzipkin/zipkin
        ports:
          - containerPort: 9411
            hostPort: 9411
---
apiVersion: v1
kind: Service
metadata:
  name: zipkin
  namespace: logging
  labels:
    k8s-app: zipkin
spec:
  type: NodePort   # NodePort   LoadBalancer
  ports:
  - port: 9411
    targetPort: 9411
    nodePort: 30002
  selector:
    k8s-app: zipkin

这样打开网址http://xxx.xxx.xxx.xxx:30002就可以打开zipkin的ui界面了

在这里插入图片描述

至于client端, 可以各自的语言下部署了.

客户端推送地址:(REST API: http://xxx.xxx.xxx.xxx:9411/api/v1/spans)

数据格式

- traceId
- name
- id
- parentId
- timestamp
- duration
- annotations: [
  endpoint: {
   ...
 }
]
- binaryAnnotations: [
  {
     - key
     - value
     - endpoint: {
      ... 
    }
 }
]

数据示例跟前面的数据示例一样

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐