0

我一直在阅读W3C Trace Context规范,但我无法通过仅查看请求中的标头来弄清楚如何获得跨度之间的子关系。

假设我正确理解了处理模型,第一个服务会生成traceparent,而后续服务会替换下游请求中parentId的。traceparent

所以服务 A 生成 atraceparent并向服务 B 发送请求:

host: service-b
traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01

服务 B 接收请求并每次更改服务 C 和服务 D 时向服务 C 和服务 D 执行两个下游请求parentId

host: service-c
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
host: service-d
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01

最后traceparent,我的请求中有 3 个

00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01
00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01

很容易看出它们都属于 trace 0af7651916cd43dd8448eb211c80319c,但是如何弄清楚它们之间的父子关系呢?

我最初的想法是这是使用 完成tracestate的,但规范指出:

tracestate 使用由一组名称/值对表示的特定于供应商的数据扩展了 traceparent。在 tracestate 中存储信息是可选的。

4

1 回答 1

0

正如您之前所说,该tracestate字段仅负责传播特定于供应商的数据。而且,它traceparent本身并没有携带足够的上下游关系信息。跟踪上下文解决了三个问题:为单个跟踪提供唯一标识符,提供商定的机制来转发特定于供应商的跟踪数据 ( tracestate),并提供中介、平台和硬件提供商可以支持的行业标准。如果您想建立上游-下游(或父子)关系,您将需要traceparent当前跨度范围的 以及上游的traceparent. 看一下 c# 中的示例.NET 5

using System;
using System.Diagnostics;

var upstreamActivity = new Activity("Upstream");

upstreamActivity.Start();
Console.WriteLine(upstreamActivity.OperationName);
Console.WriteLine("traceparent: {0}", upstreamActivity.Id);
Console.WriteLine("upstream traceparent: {0}", upstreamActivity.ParentId);
CallChildActivity();
upstreamActivity.Stop();

void CallChildActivity()
{
    var downstreamActivity = new Activity("Downstream Dependency");

    downstreamActivity.Start();
    Console.WriteLine(downstreamActivity.OperationName);
    Console.WriteLine("traceparent: {0}", downstreamActivity.Id);
    Console.WriteLine("upstream traceparent: {0}", downstreamActivity.ParentId);
    downstreamActivity.Stop();
}

stdout显示如下内容:

Upstream
traceparent: 00-192400a99d30ee459dce14655b09bc41-587841dea0e59b47-00
upstream traceparent:

Downstream Dependency
traceparent: 00-192400a99d30ee459dce14655b09bc41-d95c56215cddd74c-00
upstream traceparent: 00-192400a99d30ee459dce14655b09bc41-587841dea0e59b47-00

traceparent第一个的上游Activity是空的,这意味着:这是整个跟踪的第一个活动。另一方面,第二种方法有一个 not empty ParentId,所以这是上游活动的标识。请注意,该术语与 w3c 规范的ParentId不同,它代表上游标识。除此之外,该字段在.parent-id.NET 5parent-idspan-id.NET 5

这与 的概念相同stack trace,您需要两个 id 来建立父子关系(我在这篇文章中写过)。如果您使用的框架、中间件或库与它不同,System.Diagnostics并且它不提供 upstream traceparent,请记住,您需要在它到达新跨度范围的那一刻存储它。换句话说,在parent-id/span-id traceparent更新之前。

于 2021-05-09T18:20:37.003 回答