鏈路追蹤Tracing Analysis為分布式應(yīng)用的開(kāi)發(fā)者提供了完整的調(diào)用鏈路還原、調(diào)用請(qǐng)求量統(tǒng)計(jì)、鏈路拓?fù)洹?yīng)用依賴(lài)分析等工具,可以幫助開(kāi)發(fā)者快速分析和診斷分布式應(yīng)用架構(gòu)下的性能瓶頸,提高微服務(wù)時(shí)代下的開(kāi)發(fā)診斷效率。
官方地址:https://github.com/openzipkin/zipkin
圖片
圖片
隨著業(yè)務(wù)越來(lái)越復(fù)雜,系統(tǒng)也隨之進(jìn)行各種拆分,特別是隨著微服務(wù)架構(gòu)和容器技術(shù)的興起,看似簡(jiǎn)單的一個(gè)應(yīng)用,后臺(tái)可能有幾十個(gè)甚至幾百個(gè)服務(wù)在支撐;一個(gè)前端的請(qǐng)求可能需要多次的服務(wù)調(diào)用最后才能完成;當(dāng)請(qǐng)求變慢或者不可用時(shí),我們無(wú)法得知是哪個(gè)后臺(tái)服務(wù)引起的,這時(shí)就需要解決如何快速定位服務(wù)故障點(diǎn),zipkin分布式跟蹤系統(tǒng)就能很好的解決這樣的問(wèn)題。
圖片
微服務(wù)架構(gòu)下,一次請(qǐng)求后端會(huì)經(jīng)歷多個(gè)服務(wù)調(diào)用(所有請(qǐng)求鏈有相同的traceId和不同的spanId),都會(huì)沿著traceText帶到每一個(gè)服務(wù)中。
圖片
“
不通過(guò)Agent而直接上報(bào)數(shù)據(jù)的原理(傳統(tǒng)框架。PHP-FPM + Nginx模式)
圖片
通過(guò)Agent上報(bào)數(shù)據(jù)的原理(現(xiàn)代化框架。命令行模式)。
通過(guò)composer安裝:
composer require openzipkin/zipkin
Tracer對(duì)象可以用來(lái)創(chuàng)建Span對(duì)象(記錄分布式操作時(shí)間)。Tracer對(duì)象還配置了上報(bào)數(shù)據(jù)的網(wǎng)關(guān)地址、本機(jī)IP、采樣頻率等數(shù)據(jù),您可以通過(guò)調(diào)整采樣率來(lái)減少因上報(bào)數(shù)據(jù)產(chǎn)生的開(kāi)銷(xiāo)。
function create_tracing($endpointName, $ipv4){ $endpoint = Endpoint::create($endpointName, $ipv4, null, 2555); /* Do not copy this logger into production. * Read https://github.com/Seldaek/monolog/blob/master/doc/01-usage.md#log-levels */ $logger = new /Monolog/Logger('log'); $logger->pushHandler(new /Monolog/Handler/ErrorLogHandler()); $reporter = new Zipkin/Reporters/Http(/Zipkin/Reporters/Http/CurlFactory::create()); $sampler = BinarySampler::createAsAlwaysSample(); $tracing = TracingBuilder::create() ->havingLocalEndpoint($endpoint) ->havingSampler($sampler) ->havingReporter($reporter) ->build(); return $tracing;}
$rootSpan = $tracer->newTrace();$rootSpan->setName('encode');$rootSpan->start();try { doSomethingExpensive();} finally { $rootSpan->finish();}
以上代碼用于記錄請(qǐng)求的根操作,如果需要記錄請(qǐng)求的上一步和下一步操作,則需要傳入上下文。示例:
$span = $tracer->newChild($parentSpan->getContext());$span->setName('encode');$span->start();try { doSomethingExpensive();} finally { $span->finish();}
Client Span Server Span┌──────────────────┐ ┌──────────────────┐│ │ │ ││ TraceContext │ Http Request Headers │ TraceContext ││ ┌──────────────┐ │ ┌───────────────────┐ │ ┌──────────────┐ ││ │ TraceId │ │ │ X-B3-TraceId │ │ │ TraceId │ ││ │ │ │ │ │ │ │ │ ││ │ ParentSpanId │ │ Inject │ X-B3-ParentSpanId │Extract │ │ ParentSpanId │ ││ │ ├─┼─────────>│ ├────────┼>│ │ ││ │ SpanId │ │ │ X-B3-SpanId │ │ │ SpanId │ ││ │ │ │ │ │ │ │ │ ││ │ Sampled │ │ │ X-B3-Sampled │ │ │ Sampled │ ││ └──────────────┘ │ └───────────────────┘ │ └──────────────┘ ││ │ │ │└──────────────────┘ └──────────────────┘
開(kāi)通ARMS地址 https://arms.console.aliyun.com/ (一般有15天試用)
進(jìn)入 https://tracing.console.aliyun.com/#/globalSetting/cn-hangzhou/process 按照?qǐng)D示獲得接入點(diǎn)url地址。
圖片
如果你的服務(wù)器在阿里云上可以用阿里云vpc網(wǎng)絡(luò)接入點(diǎn),本示例用的是阿里云公網(wǎng)接入點(diǎn)。
通過(guò)composer安裝:
composer require openzipkin/zipkin
鏈路監(jiān)控中間件 app/middleware/ArmsMiddleware.php
<?php/** * @desc 全鏈路監(jiān)控中間件 * @author Tinywan(ShaoBo Wan) * @date 2021/12/6 14:06 */declare(strict_types=1);namespace app/middleware;use Monolog/Handler/ErrorLogHandler;use Monolog/Logger;use support/Log;use think/facade/Db;use Webman/MiddlewareInterface;use Webman/Http/Response;use Webman/Http/Request;use Zipkin/Reporters/Http;use Zipkin/TracingBuilder;use Zipkin/Samplers/BinarySampler;use Zipkin/Endpoint;use Workerman/Timer;use const Zipkin/Tags/SQL_QUERY;class ArmsMiddleware implements MiddlewareInterface{ /** * @desc: 方法描述 * @param Request $request * @param callable $next * @return Response * @author Tinywan(ShaoBo Wan) */ public function process(Request $request, callable $next) : Response { static $tracing = null, $tracer = null; if (!$tracing) { $endpoint = Endpoint::create('開(kāi)源技術(shù)小棧', $request->getRealIp(), null, 2555); $logger = new Logger('log'); $logger->pushHandler(new ErrorLogHandler()); $reporter = new Http(['endpoint_url' => config('security')['endpoint_url']]); $sampler = BinarySampler::createAsAlwaysSample(); $tracing = TracingBuilder::create() ->havingLocalEndpoint($endpoint) ->havingSampler($sampler) ->havingReporter($reporter) ->build(); $tracer = $tracing->getTracer(); // 55秒上報(bào)一次,盡量將上報(bào)對(duì)業(yè)務(wù)的影響減少到最低 Timer::add(55, function () use ($tracer) { $tracer->flush(); }); register_shutdown_function(function () use ($tracer) { $tracer->flush(); }); } $rootSpan = $tracer->newTrace(); $rootSpan->setName($request->controller."::".$request->action); $rootSpan->start(); $request->rootSpan = $rootSpan; $request->tracer = $tracer; $result = $next($request); // 統(tǒng)計(jì)sql(日志在內(nèi)存) if (class_exists(Db::class)) { $logs = Db::getDbLog(true); if (!empty($logs['sql'])) { foreach ($logs['sql'] as $sql) { $sqlSpan = $tracer->newChild($rootSpan->getContext()); $sqlSpan->setName(SQL_QUERY); $sqlSpan->start(); $sqlSpan->tag('db.statement', $sql); $sqlSpan->finish(); } } } $rootSpan->finish(); return $result; }}
在 config/middleware.php 中添加全局中間件如下:
return [ '' => [ /app/middleware/ArmsMiddleware::class, ], ...];
訪(fǎng)問(wèn)地址 https://tracing.console.aliyun.com/ ,效果類(lèi)似如下:
圖片
圖片
本文鏈接:http://www.www897cc.com/showinfo-26-93091-0.htmlPHP 服務(wù)實(shí)現(xiàn)性能剖析、跟蹤和可觀察性14444444444444】=102102102102102102102102102102102102102102102102實(shí)踐
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: 震驚!用 Suspense 解決請(qǐng)求依賴(lài)的復(fù)雜場(chǎng)景居然這么簡(jiǎn)單!