我实际上试图在我的应用程序中只对错误轨迹进行采样,但我的应用程序中已经设置了一个概率采样器参数,该参数在开始时对跨度本身进行采样,其余跨度遵循相同的模式之后,我尝试在 Jaeger 中使用力采样选项,但它似乎并没有覆盖由初始跨度做出的原始决定是否采样。 请在这里帮助我。
Jaeger 客户端实现了所谓的基于头部的采样,其中采样决策在调用树的根部做出,并与跟踪上下文一起沿树向下传播。这样做是为了保证对给定跟踪的所有跨度(或没有一个(进行一致的采样,因为我们不想让硬币在每个节点上翻转并最终得到部分/损坏的跟踪。在基于头部的采样系统中实现错误采样实际上是不可能的。映像您的服务正在调用成功返回的服务 A,然后调用返回错误的服务 B。假设未对跟踪的根进行采样(因为否则您通常会捕获错误(。这意味着当您知道来自 B 的错误时,A 处的整个子树已经执行,并且由于之前决定不采样而丢弃所有跨度。B 处的子树也已完成执行。此时唯一可以采样的是当前服务中的跨度。您还可以通过响应调用方来实现采样决策的反向传播。因此,在最好的情况下,您最终可能会得到整个跟踪采样的子分支,如果跟踪从上面继续(例如通过重试(,则可能的未来分支。但是您永远无法捕获完整的跟踪,有时 B 失败的原因是 A(成功(返回了一些后来导致错误的数据。
请注意,目前 OpenTracing 或 OpenTelemetry 不支持反向传播,但在 W3C 跟踪上下文工作组的上次会议上已经讨论了反向传播。
实现采样的替代方法是使用基于尾部的采样,这是当今一些商业供应商采用的技术,例如Lightstep,DataDog。它也在Jaeger的路线图上(我们现在在Uber上工作(。使用基于尾部的采样时,从应用程序捕获 100% 的跨度,但仅存储在收集层的内存中,直到收集完整跟踪并做出采样决策。决策代码现在有了更多的信息,包括错误、异常延迟等。如果我们决定对跟踪进行采样,则只有这样它才会进入磁盘存储,否则我们会将其从内存中逐出,这样我们只需要在内存中平均保留几秒钟的跨度。基于尾部的采样会对跟踪的应用程序施加更严重的性能损失,因为 100% 的流量需要由跟踪检测进行分析。
您可以在我的书(https://www.shkuro.com/books/2019-mastering-distributed-tracing/(的第3章或精彩的论文"所以,你想跟踪你的分布式系统吗?来自多年实践经验的关键设计见解">,作者:Raja R. Sambasivan、Rodrigo Fonseca、Ilari Shafer、Gregory R. Ganger (http://www.pdl.cmu.edu/PDL-FTP/SelfStar/CMU-PDL-14-102.pdf(。