Hyperf方案 链路追踪(Zipkin/Jaeger)

张开发
2026/4/17 14:33:29 15 分钟阅读

分享文章

Hyperf方案 链路追踪(Zipkin/Jaeger)
Hyperf 官方已内置 hyperf/tracer基于 OpenTracing 标准同时支持 Zipkin 和 Jaeger。 ┌──────┬────────┬─────────────────────┐ │ │ Zipkin │ Jaeger │ ├──────┼────────┼─────────────────────┤ │ 部署 │ 更轻量 │ UI 更强采样更灵活 │ ├──────┼────────┼─────────────────────┤ │ 推荐 │ 小团队 │ 生产环境 │ └──────┴────────┴─────────────────────┘ --- 安装composerrequire hyperf/tracer php bin/hyperf.php vendor:publish--idhyperf.tracer ---1. 配置二选一 config/autoload/opentracing.php?phpreturn[defaultenv(TRACER_DRIVER,jaeger),tracer[// Jaegerjaeger[driver\Hyperf\Tracer\Adapter\JaegerTracerFactory::class,nameenv(APP_NAME,hyperf),options[sampler[type\Jaeger\SAMPLER_TYPE_CONST,paramtrue,],local_agent[reporting_hostenv(JAEGER_HOST,127.0.0.1),reporting_portenv(JAEGER_PORT,5775),],],], // Zipkinzipkin[driver\Hyperf\Tracer\Adapter\ZipkinTracerFactory::class,nameenv(APP_NAME,hyperf),options[endpoint_urlenv(ZIPKIN_ENDPOINT,http://127.0.0.1:9411/api/v2/spans),timeout1,],],],];---2. 自动追踪零代码 框架自动追踪以下组件无需任何代码 // config/autoload/aspects.php - 确认已启用return[\Hyperf\Tracer\Aspect\HttpClientAspect::class, // Guzzle HTTP\Hyperf\Tracer\Aspect\RedisAspect::class, // Redis\Hyperf\Tracer\Aspect\DbAspect::class, // 数据库查询\Hyperf\Tracer\Aspect\GrpcAspect::class, // gRPC];---3. 自定义 Span?php namespace App\Service;use Hyperf\Tracer\SpanStarter;class OrderService{use SpanStarter;publicfunctioncreateOrder(int$userId, array$items): array{$span$this-startSpan(order.create);$span-setTag(user.id,$userId);$span-setTag(items.count, count($items));try{$orderOrder::create([user_id$userId,totalcollect($items)-sum(price),]);$span-setTag(order.id,$order-id);return$order-toArray();}catch(\Throwable$e){$span-setTag(error,true);$span-log([message$e-getMessage()]);throw$e;}finally{$span-finish();}}}---4. 跨服务传播HTTP 请求?php namespace App\Middleware;use Hyperf\Tracer\SpanStarter;use OpenTracing\Formats;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\MiddlewareInterface;use Psr\Http\Server\RequestHandlerInterface;class TracingMiddleware implements MiddlewareInterface{use SpanStarter;publicfunctionprocess(ServerRequestInterface$request, RequestHandlerInterface$handler): ResponseInterface{// 从上游提取 trace context$context$this-tracer-extract(Formats\HTTP_HEADERS,$request-getHeaders());$span$this-startSpan(name:$request-getMethod(). .$request-getUri()-getPath(), options:[child_of$context],);$span-setTag(http.method,$request-getMethod());$span-setTag(http.url,(string)$request-getUri());try{$response$handler-handle($request);$span-setTag(http.status_code,$response-getStatusCode());return$response;}catch(\Throwable$e){$span-setTag(error,true);$span-log([message$e-getMessage()]);throw$e;}finally{$span-finish();}}}向下游注入 context use GuzzleHttp\Client;use OpenTracing\Formats;$headers[];$this-tracer-inject($span-getContext(), Formats\HTTP_HEADERS,$headers);$clientnew Client();$client-post(http://order-service/api/orders,[headers$headers,json$payload,]);---5. Docker 快速启动# docker-compose.ymlservices: jaeger: image: jaegertracing/all-in-one:latest ports: -5775:5775/udp# agent-16686:16686# UIenvironment: COLLECTOR_ZIPKIN_HOST_PORT:9411zipkin: image: openzipkin/zipkin:latest ports: -9411:9411# UI API--- 核心要点 - SpanStarter trait 是关键自动注入 tracer 实例 - DB/Redis/HTTP 已自动追踪只需对业务关键路径手动埋点 - 跨服务必须 inject/extract 传播 context否则 trace 断链 - 生产环境建议 Jaeger 概率采样SAMPLER_TYPE_PROBABILISTIC param:0.110%

更多文章