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下,这样就会显示关联关系了。如果还是看不到,先检查:- 上游请求是否真的发送了
traceparent头 - 下游是否正确提取并使用了这个头生成Span
- 两个服务的Tracer配置是否都指向同一个Jaeger Collector
- 上游请求是否真的发送了
内容的提问来源于stack exchange,提问作者nnikolay
相关产品推荐
相关产品推荐

