【zipkin】链路追踪

1,安装zipkin:https://zipkin.io/pages/quickstart.html

推荐使用docker去安装zipkin服务,下载安装执行都有了。缺点是下载要等待一段时间

2,使用php来构造tracing数据,投递给zipkin

用的包是:https://github.com/jcchavezs/zipkin-php

安装推荐使用composer,找个空目录直接执行composer命令就好

实战1:demo先跑起来

<?php
require "vendor/autoload.php";

use ZipkinAnnotation;
use ZipkinEndpoint;     
use ZipkinSamplersBinarySampler;
use ZipkinTracingBuilder;
use ZipkinReportersHttp;

$endpoint = Endpoint::createFromGlobals();

$reporter = new Http();  
$sampler = BinarySampler::createAsAlwaysSample();
$tracing = TracingBuilder::create()
    ->havingLocalEndpoint($endpoint)
    ->havingSampler($sampler) 
    ->havingReporter($reporter)
    ->build();           

$tracer = $tracing->getTracer();

$span = $tracer->newTrace();
$span->setName("encode");
$span->start();
try {
    usleep(100000);

} finally {
    $span->finish();
}


$tracer->flush();

执行以上脚本,打开zipkin的查看界面:127.0.0.1:9411,找到cli然后可以看到一条追踪记录。

可以看到zipkin的查看界面中多了条tracing记录。

这里需要解释下图中的东西:

1,cli:是serviceName,对应于你的服务名称(比如图片服务等)

2,执行时间:100ms,对应这次服务时间,从请求到相应是100ms;

3,encode;这个表示span的名称,span在zipkin的函数是某个节点(或者记录),和html的span有类似的含义。是个树状结构,可以有平级兄弟,和父子节点。

再次解释下图中的东西和原始数据的关系:

1,cli是serviceName,它是在这个动作中埋入的:Endpoint::createFromGlobals(),可以看到源码中有:new self(PHP_SAPI, ...);

2,执行时间:100ms,对应到usleep函数;

3,encode:是span的名称,对应的函数是setName()操作。

然后我们来分析下tracing主要做的事情:

1,在每个节点处(span)打点,初始化时设置context上下文(暂时忽略这个概念),name(span名称);

2,span节点开始时执行start操作,记录当前时间戳;

3,span节点结束时执行finish操作,记录结束时间戳;

这样就产生了一条span记录,包含:context,span-name,start-time,end-time。

然后我们再理解下context有哪些数据项。

traceId:追踪链的根节点id,刚才说span是树状结构,那么就需要个根节点id,类似于root-id;

spanId:当前span节点的id,和树的node-id是类似的;

parentId:当前span的父节点id,和树的parent-id是类似的;

context中可以设置traceId,和parentId,需要上下文传递过来,接下来有具体的例子来设置span的context。

spanId如何设置的呢?$tracer->newTrace() 这个操作是生成一个新的span节点,生成节点时会先生成TraceContext,同步会初始化spanId。

实战2:生成父子节点,生成兄弟节点

<?php
require "vendor/autoload.php";

use ZipkinAnnotation;
use ZipkinEndpoint;     
use ZipkinSamplersBinarySampler;
use ZipkinTracingBuilder;
use ZipkinReportersHttp;

$endpoint = Endpoint::createFromGlobals();
$endpoint = Endpoint::create("php-demo");

$reporter = new Http();
$sampler = BinarySampler::createAsAlwaysSample();
$tracing = TracingBuilder::create()
    ->havingLocalEndpoint($endpoint)
    ->havingSampler($sampler) 
    ->havingReporter($reporter)
    ->build();

$tracer = $tracing->getTracer();

$span = $tracer->newTrace();
$span->setName("encode");
$span->start();
try {
    $parentContext = $span->getContext();
    $childSpan = $tracer->newChild($parentContext);
    $childSpan->setName("encode1");
    $childSpan->start();
    usleep(100000);
    $childSpan->finish();
    
    $childSpan2 = $tracer->newChild($parentContext);
    $childSpan2->setName("encode2");
    $childSpan2->start();
    usleep(100000);
    $childSpan2->finish();    

} finally {
    $span->finish();
}


$tracer->flush();

zipkin的追踪结果:

可以看到有三个span,encode是根节点,有两个儿子(encode1和encode2)。

重点就是newChild($parentContext),把父节点的信息传入到新的span节点就能实现两者之间的对应关系了。

相关的文章链接:

zipkin核心数据结构:https://my.oschina.net/guol/blog/871678

zipkin api接口:https://zipkin.io/zipkin-api/#/default/post_spans

zipkin api文档:https://github.com/openzipkin/zipkin-api/blob/master/zipkin-api.yaml#L56

jwt入门介绍:https://www.cnblogs.com/zaixiuxing/p/6005968.html

golang body长度:https://stackoverflow.com/questions/43021058/golang-read-request-body

原文地址:https://www.cnblogs.com/helww/p/8438502.html