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 Zipkin\Annotation; use Zipkin\Endpoint; use Zipkin\Samplers\BinarySampler; use Zipkin\TracingBuilder; use Zipkin\Reporters\Http; $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 Zipkin\Annotation; use Zipkin\Endpoint; use Zipkin\Samplers\BinarySampler; use Zipkin\TracingBuilder; use Zipkin\Reporters\Http; $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