概述

所有 Jaeger 客户端库都支持 OpenTracing API。
以下内容包括了有关使用 OpenTracing 注入应用程序的相关文档:

本文主要内容包含有关在已使用 OpenTracing API 注入的应用程序中配置和实例化 Jaeger Tracer的相关讲解。

术语说明

在本文中,我们将会使用到如下一些术语:

  • 客户端库
  • 注入库
  • tracer等

支持的库

Jaeger 官方支持如下客户端库:

Language Github Repo
Go jaegertracing/jaeger-client-go
Java jaegertracing/jaeger-client-java
Node.js jaegertracing/jaeger-client-node
Python jaegertracing/jaeger-client-python
C++ jaegertracing/jaeger-client-cpp
C# jaegertracing/jaeger-client-csharp

针对其他语言的客户端库目前仍处于开发阶段,可以参考 Issue

初始化 Jaeger Tracer

每种语言的初始化语法略有不同,请参阅各自存储库中的 README。
一般的模式不显式创建 Tracer,而是使用 Configuration 类来实现。
Configuration 允许更简单的 Tracer 参数化,例如更改默认采样规则或 Jaeger Agent的地址。

Tracer 内部

采样

参考采样一文。

上报器

Jaeger Tracer 使用 reporter 来处理 finished 状态的 span。
通常,Jaeger 库附带以下 reporter :

  • NullReporter 对 span 没有任何作用。 它在单元测试中很有用。
  • LoggingReporter 只是简单地记录一个 span 完成的信息,通常是打印trace和span ID 以及操作名称。
  • CompositeReporter 获取reporter的列表并一一调用它们。
  • RemoteReporter(默认)在内存中缓冲一定数量的完成的span,并使用reporter将一批span提交到 Jaeger 后端。 reporter负责将 span 序列化为固定的格式(例如 Thrift 或 JSON)并与后端组件通信(例如通过 UDP 或 HTTP)。

EMSGSIZE and UDP 缓冲区限制

默认情况下,Jaeger 库使用 UDP sender 向 jaeger-agent daemon进程上报完成的span数据。
默认最大数据包大小为 65,000 字节,通过环回接口连接到Agent时可以不分段传输。
但是,某些操作系统(尤其是 MacOS)会限制 UDP 数据包的最大缓冲区大小。
如果遇到 EMSGSIZE 错误的问题,请考虑提高内核中的限制(请参阅问题以获取示例)。
您还可以将客户端库配置为使用较小的最大数据包大小,但如果span较大,则可能会导致问题。超过最大数据包大小的span数据将被客户端丢弃。
另一种选择是使用非 UDP 传输,例如 Java 中的 HttpSender(目前并非适用于所有语言)。

指标

Jaeger tracer 会记录各种指标数据。这些指标包括它们已开始和完成的span或trace数量,其中有多少被采样或未采样,以及在解码来自入站请求的span context 或向后端发送 span 数据时存在任何错误。

传播格式

当 SpanContext 在传播链路上作为对另一个服务的请求的一部分进行编码时,Jaeger 客户端库默认为其指定为 Jaeger native propagation 格式。
此外,Jaeger 客户端支持 Zipkin B3 格式W3C Trace-Context 格式

Trace/Span唯一标识

Key

uber-trace-id

  • HTTP 不区分大小写
  • 保留标头大小写的协议中的小写

Value

{trace-id}:{span-id}:{parent-span-id}:{flags}

  • {trace-id}
    • base16 格式的 64 位或 128 位随机数。
    • 可以是可变长度,不足位数则左侧填充 0。
    • 某些语言的客户端支持 128 位。
    • 不允许为0。
  • {span-id}
    • base16 格式的 64 位随机数。
    • 可以是可变长度,不足位数则左侧填充 0。
    • 不允许为0。
  • {parent-span-id}
    • base16 格式的 64 位随机数,表示父span的ID。
    • 已弃用,大多数 Jaeger 客户端忽略接收端,但仍将其包含在发送端。
    • 0 值有效,表示“根跨度”。
  • {flags}
    • 一个字节的bitmap,表示为一到两个十六进制数。
    • 最右边(最低有效位)是“采样”标志,1 表示对跟踪进行采样,并建议所有下游服务均采样;0 表示不采样。
    • 右边第二位表示debug标记,仅在设置采样标志时才应设置debug标志,表明通知后端服务尽量不要丢弃该trace信息。
    • 右边第四位表示firehose标记,标记为“firehose”的span将不会进行存储,trace信息只能根据trace id 从日志中进行检索。
    • 其他位数暂时没用。

Baggage

  • Key: uberctx-{baggage-key}
  • Value: 编码后得到的一个字符串
  • 限制: 由于 HTTP 标头不保留大小写,Jaeger 建议Baggage为小写且用减号连接,例如my-baggage-key-1。

例如示例代码如下:

  1. span.SetBaggageItem("key1", "value1")
  2. span.SetBaggageItem("key2", "value2")

实际上发送的HTTP Headers头部为:

  1. uberctx-key1: value1
  2. uberctx-key2: value2

值编码

OpenTracing 为纯文本标头定义了两种格式:HTTP_HEADERS 和 TEXT_MAP。
前者是为了处理 HTTP 协议对标头上下文施加的限制,而后者不施加任何限制,例如它可以与 Kafka 记录头一起使用。
Jaeger SDK 中这两种格式的主要区别在于,当使用 HTTP_HEADERS 传播格式时,Baggage Value是 URL 编码的。

示例:使用 HTTP_HEADERS 传播格式时,代码序列如下:

  1. span.SetBaggageItem("key1", "value 1 / blah")

实际的 HTTP Header的内容如下:

  1. uberctx-key1: value%201%20%2F%20blah