You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenTelemetry for PHP跨API请求无法关联微服务问题求助

解决OpenTelemetry PHP微服务链路在Jaeger中无关联的问题

这种情况基本都是Trace上下文没有在服务间正确传递导致的,按下面的步骤排查修复:

  • 给Guzzle客户端添加OpenTelemetry中间件,自动注入Trace头
    上游服务用Guzzle调用下游时,必须通过OpenTelemetry的Guzzle中间件把当前Trace的上下文(traceparent等头)带到请求里,否则下游不知道自己属于哪个Trace。示例代码:

    use OpenTelemetry\Contrib\Guzzle\OtelMiddleware;
    use GuzzleHttp\Client;
    
    // 确保全局Tracer已正确初始化
    $tracer = \OpenTelemetry\API\Trace\TracerProvider::getDefault()->getTracer('service1');
    
    // 给Guzzle handler包裹OpenTelemetry中间件
    $handlerStack = \GuzzleHttp\HandlerStack::create();
    $handlerStack->push(OtelMiddleware::create($tracer));
    
    $client = new Client(['handler' => $handlerStack]);
    // 发起请求时会自动携带Trace头
    $client->get('http://service2/api/products/1');
    
  • 下游服务要正确提取Trace上下文
    下游服务(service2)的HTTP入口处,必须从请求头里提取traceparent,把当前Span关联到上游的Trace上。如果用的是Laravel/Symfony这类框架,建议用官方的OpenTelemetry集成包,会自动处理这个逻辑;如果是自定义入口,手动提取的示例:

    use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
    
    $propagator = TraceContextPropagator::getInstance();
    // 从请求头中获取载体,这里用$_SERVER示例,实际根据框架调整
    $carrier = array_filter($_SERVER, fn($key) => str_starts_with($key, 'HTTP_'));
    // 提取上下文并设置为当前上下文
    $context = $propagator->extract($carrier);
    \OpenTelemetry\Context\Context::storage()->attach($context);
    
    // 之后创建的Span会自动关联到上游的Trace
    $tracer = \OpenTelemetry\API\Trace\TracerProvider::getDefault()->getTracer('service2');
    $span = $tracer->spanBuilder('service2.products.get')->startSpan();
    
  • 验证Trace ID一致性
    修复后,在Jaeger里搜索上游服务的Trace ID,应该能看到上下游两个服务的Span都在同一个Trace下,这样就会显示关联关系了。如果还是看不到,先检查:

    1. 上游请求是否真的发送了traceparent头
    2. 下游是否正确提取并使用了这个头生成Span
    3. 两个服务的Tracer配置是否都指向同一个Jaeger Collector

内容的提问来源于stack exchange,提问作者nnikolay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 03:22:04