How to Integrate Zipkin Distributed Tracing with Webman and Alibaba Cloud ARMS
This guide explains Zipkin's architecture, data reporting methods, and step‑by‑step integration with the Webman framework, including middleware implementation, configuration, and visual monitoring on Alibaba Cloud ARMS, enabling developers to trace requests, monitor SQL, and diagnose performance issues in microservice environments.
Zipkin Overview
Zipkin is an open‑source distributed tracing system that reconstructs call chains, aggregates request statistics, visualizes topology, and analyzes service dependencies, helping developers diagnose performance bottlenecks in microservice architectures.
Architecture
Clients instrument applications using language‑specific SDKs that implement the OpenTracing standard. Tracing data is sent to a Zipkin backend, which aggregates, stores, and provides real‑time views such as trace details, performance overviews, and service topology. The data can be exported to downstream services for offline analysis or alerting.
Data Reporting Options
Direct reporting from traditional PHP frameworks (e.g., ThinkPHP 6.0, Laravel, Yii 2.0) without an agent.
Agent‑based reporting for modern command‑line frameworks such as Webman.
Webman Quick‑Start
1. Enable Alibaba Cloud ARMS
Visit the ARMS console at https://arms.console.aliyun.com/ and enable the service (typically a 15‑day trial).
2. Obtain the reporting endpoint URL
In the Tracing console global settings (https://tracing.console.aliyun.com/#/globalSetting/cn-hangzhou/process) copy the data‑reporting endpoint. Use a public endpoint unless the server resides in an Alibaba Cloud VPC.
3. Install Zipkin SDK
composer require openzipkin/zipkin4. Implement Middleware
Create app\middleware\ArmsMiddleware.php to initialize a Zipkin tracer, schedule periodic flushing, and record root spans, request information, and SQL queries.
<?php
declare(strict_types=1);
namespace app\middleware;
use Monolog\Handler\ErrorLogHandler;
use Monolog\Logger;
use think\facade\Db;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use Zipkin\Reporters\Http as HttpReporter;
use Zipkin\TracingBuilder;
use Zipkin\Samplers\BinarySampler;
use Zipkin\Endpoint;
use Workerman\Timer;
use const Zipkin\Tags\SQL_QUERY;
class ArmsMiddleware implements MiddlewareInterface {
public function process(Request $request, callable $next): Response {
static $tracing = null, $tracer = null;
if (!$tracing) {
$endpoint = Endpoint::create('OpenTechStack', $request->getRealIp(), null, 2555);
$logger = new Logger('log');
$logger->pushHandler(new ErrorLogHandler());
$reporter = new HttpReporter(['endpoint_url' => config('security')['endpoint_url']]);
$sampler = BinarySampler::createAsAlwaysSample();
$tracing = TracingBuilder::create()
->havingLocalEndpoint($endpoint)
->havingSampler($sampler)
->havingReporter($reporter)
->build();
$tracer = $tracing->getTracer();
Timer::add(55, fn() => $tracer->flush());
register_shutdown_function(fn() => $tracer->flush());
}
$rootSpan = $tracer->newTrace();
$rootSpan->setName($request->controller . "::" . $request->action);
$rootSpan->start();
$request->rootSpan = $rootSpan;
$request->tracer = $tracer;
$result = $next($request);
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;
}
}5. Register Middleware Globally
return [
'' => [
\app\middleware\ArmsMiddleware::class,
],
// ... other middleware
];6. View Tracing Results
Open the Alibaba Cloud Tracing console at https://tracing.console.aliyun.com/ to view interface and database monitoring dashboards.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
