传播

PHP API 的上下文传播

通过上下文传播,信号可以相互关联,无论它们在何处生成。虽然不仅限于追踪,但上下文传播允许追踪在跨越任意分布式进程和网络边界的服务中构建系统的因果信息。

对于绝大多数用例,原生支持 OpenTelemetry 的库或仪器库会为您自动跨服务传播追踪上下文。只有在极少数情况下,您才需要手动传播上下文。

要了解更多信息,请参阅上下文传播

传播是将数据在服务和进程之间传递的机制。尽管传播不仅限于跟踪,但它允许跨越任意分布式进程和网络边界的服务构建系统的因果关系信息。

OpenTelemetry 提供了一种基于文本的方法,使用 W3C Trace Context HTTP 标头将上下文传播到远程服务。

自动上下文传播

一些最流行的框架、库和 PHP 扩展已经提供了自动检测功能。其中许多执行传入和/或传出上下文传播,并且可以通过 注册表Packagist 找到。

传入请求

可以使用多种方式自动处理上下文传播

  • 通过使用受支持的 PHP 框架(例如:Laravel、Symfony、Slim)及其相应的自动检测包
  • 通过在代码中实现 PSR-15 RequestHandlerInterface 及其相应的自动检测包
  • 通过使用实验性的 自动根跨度 功能

传出请求

HTTP 客户端和接口的自动检测包会自动将 W3C tracecontext 标头注入到传出的 HTTP 请求中。

手动上下文传播

在某些情况下,无法使用检测库来传播上下文。可能没有与您用来让服务相互通信的库匹配的检测库。或者,即使检测库存在,您的需求也无法满足。

当您必须手动传播上下文时,请使用上下文 API。

以下代码段显示了一个传出 HTTP 请求的示例

$request = new Request('GET', 'https://:8080/resource');
$outgoing = $tracer->spanBuilder('/resource')->setSpanKind(SpanKind::CLIENT)->startSpan();
$outgoing->setAttribute(TraceAttributes::HTTP_METHOD, $request->getMethod());
$outgoing->setAttribute(TraceAttributes::HTTP_URL, (string) $request->getUri());

$carrier = [];
TraceContextPropagator::getInstance()->inject($carrier);
foreach ($carrier as $name => $value) {
    $request = $request->withAddedHeader($name, $value);
}
try {
    $response = $client->send($request);
} finally {
    $outgoing->end();
}

同样,使用基于文本的方法从传入请求中读取 W3C Trace Context。以下是一个处理传入 HTTP 请求的示例

$request = ServerRequestCreator::createFromGlobals();
$context = TraceContextPropagator::getInstance()->extract($request->getHeaders());
$root = $tracer->spanBuilder('HTTP ' . $request->getMethod())
    ->setStartTimestamp((int) ($request->getServerParams()['REQUEST_TIME_FLOAT'] * 1e9))
    ->setParent($context)
    ->setSpanKind(SpanKind::KIND_SERVER)
    ->startSpan();
$scope = $root->activate();
try {
    /* do stuff */
} finally {
    $root->end();
    $scope->detach();
}

下一步

有关传播的更多信息,请阅读 传播器 API 规范