概述

Jaeger 由不同的组件组成,每个组件都可能在自己的机器上运行。
可能是这些组件之一不能正常工作,导致无法处理和存储span数据。
当出现问题时,请务必检查此处列出的可能的问题列表。

检查采样策略

在做任何其他事情之前,首先请确认当前正在使用的采样策略。
默认情况下,Jaeger 使用 probabilistic 抽样策略,有 1/1000 的概率上报span数据。
但是,出于开发目的或者在流量不大的场景,对每个trace都进行采样是正常的。

通常,可以通过环境变量 JAEGER_SAMPLER_TYPE 和 JAEGER_SAMPLER_PARAM 设置采样策略,但请参阅 Jaeger Client 的文档以了解您所使用的语言,了解有关可用采样策略的更多详细信息。
使用 Jaeger Java Client 时,采样策略通常通过创建Tracer时被注入的Lib库在应用程序提供的日志记录工具打印出来:

  1. 2018-12-10 16:41:25 INFO Configuration:236 - Initialized tracer=JaegerTracer(..., sampler=ConstSampler(decision=true, tags={sampler.type=const, sampler.param=true}), ...)

在定位其他组件未接收到span的原因时,请确保将客户端配置为对每个trace进行采样,将 JAEGER_SAMPLER_TYPE 环境变量设置为 const,并将 JAEGER_SAMPLER_PARAM 设置为 1。

打开上报日志

大多数 Jaeger 客户端都能够打印客户端库注入应用程序后上报跨度的相关日志。
通常,这可以通过将环境变量 JAEGER_REPORTER_LOG_SPANS 设置为 true 来完成,但请参阅 Jaeger Client 的文档以了解您使用的语言。
在某些语言中,特别是在 Go 和 Node.js 中,没有标准日志记录工具,因此您需要将logger显式传递给客户端,该 logger 需要实现由 Jaeger 客户端定义的的 Logger 接口。
使用 Jaeger Java Client 时,spans 报告如下:

  1. 2018-12-10 17:20:54 INFO LoggingReporter:43 - Span reported: e66dc77b8a1e813b:6b39b9c18f8ef082:a56f41e38ca449a4:1 - getAccountFromCache

上面的日志信息包含三个 ID:trace ID e66dc77b8a1e813b、span ID 6b39b9c18f8ef082 和 span parent ID a56f41e38ca449a4。
当后端组件将日志级别设置为debug时,span和trace ID 应该在其标准输出中可见(请参阅下面的“增加后端组件中的日志记录”下的更多信息)。

日志打印机制也遵循采样器做出的采样决定,这意味着如果打印了span信息,它也应该到达Agent或Collector。

绕过 Jaeger Agent

默认情况下,Jaeger 客户端配置为通过 UDP 将 Span 发送到在本地主机上运行的 Jaeger Agent。
由于某些网络设置可能会丢弃或阻止 UDP 数据包,或强加大小限制,因此可以将 Jaeger 客户端配置为绕过代理,将span数据直接发送到Collector。
一些客户端,如 Jaeger Java Client,支持环境变量 JAEGER_ENDPOINT,可用于指定Collector的位置,如 http://jaeger-collector:14268/api/traces
有关您使用的语言,请参阅 Jaeger 客户端的文档。
例如,当您在 Jaeger Java Client 中配置了 JAEGER_ENDPOINT 属性时,它会在创建Tracer时记录以下内容(注意 sender=HttpSender):

  1. 2018-12-10 17:06:30 INFO Configuration:236 - Initialized tracer=JaegerTracer(..., reporter=CompositeReporter(reporters=[RemoteReporter(sender=HttpSender(), ...), ...]), ...)

Ps:当无法建立到 Jaeger Collector 的连接时,Jaeger Java Client 不会失败。Span 将被收集并放置在内部缓冲区中。一旦建立连接,它们可能最终会到达Collector,或者在缓冲区达到其最大大小时被丢弃。

如果您的 Jaeger 后端仍然无法接收 Span(请参阅以下有关如何检查日志和指标的部分),那么问题很可能与您的网络命名空间配置有关。
将 Jaeger 后端组件作为 Docker 容器运行时,典型的错误是:

  • 没有将需要的端口对外暴露,例如Collector监听的端口是14268,但是容器外部无法正常访问该端口。
  • Agent 或者 Collector 的服务名称在应用程序环境下无法发现该服务。例如,如果您在 Docker 的不同容器中同时运行您的应用程序和 Jaeger 后端,则它们要么需要位于同一命名空间中,要么需要使用 docker 命令的 —link 选项为应用程序的容器授予对 Jaeger 后端的访问权限。

增加后端组件日志

当日志级别设置为debug时,Jaeger agent和collector会提供有用的调试信息。
agent 收到的每个 UDP 数据包以及agent发送到collector的每组span都会被打印出来。
collector 还记录它接收的每组span数据并记录存储在后端存储中的每个span。

以下是使用 —log-level=debug 标志启动 Jaeger Agent 时的预期结果:

  1. {"level":"debug","ts":1544458854.5367086,"caller":"processors/thrift_processor.go:113","msg":"Span(s) received by the agent","bytes-received":359}
  2. {"level":"debug","ts":1544458854.5408711,"caller":"tchannel/reporter.go:133","msg":"Span batch submitted by the agent","span-count":3}

对于 Jaeger Collector 而言,指定 —log-level=debug 参数后,日志格式如下:

  1. {"level":"debug","ts":1544458854.5406284,"caller":"app/span_handler.go:90","msg":"Span batch processed by the collector.","ok":true}
  2. {"level":"debug","ts":1544458854.5406587,"caller":"app/span_processor.go:105","msg":"Span written to the storage by the collector","trace-id":"e66dc77b8a1e813b","span-id":"6b39b9c18f8ef082"}
  3. {"level":"debug","ts":1544458854.54068,"caller":"app/span_processor.go:105","msg":"Span written to the storage by the collector","trace-id":"e66dc77b8a1e813b","span-id":"d92976b6055e6779"}
  4. {"level":"debug","ts":1544458854.5406942,"caller":"app/span_processor.go:105","msg":"Span written to the storage by the collector","trace-id":"e66dc77b8a1e813b","span-id":"a56f41e38ca449a4"}

查询监控指标

对于无法设置Collector日志为debug模式的场景下,可以使用 /metrics url来检查是否收到了特定服务的跨度。
/metrics url 从 admin 端口提供服务。
假设 Jaeger Collector 在名为 jaeger-collector 的主机下可用,以下是获取指标的示例 curl 调用:

  1. curl http://jaeger-collector:14269/metrics

以下指标非常值得关注:

  1. jaeger_collector_spans_received
  2. jaeger_collector_spans_saved_by_svc
  3. jaeger_collector_traces_received
  4. jaeger_collector_traces_saved_by_svc

对于同一个服务,前两个指标的值应该差不多。同样,两个Trace指标的值应该也差不多。
例如,这是一个按正常工作的服务结果示例:

  1. jaeger_collector_spans_received{debug="false",format="jaeger",svc="order"} 8
  2. jaeger_collector_spans_saved_by_svc{debug="false",result="ok",svc="order"} 8
  3. jaeger_collector_traces_received{debug="false",format="jaeger",svc="order"} 1
  4. jaeger_collector_traces_saved_by_svc{debug="false",result="ok",svc="order"} 1

Istio: 丢失span

当将您的应用程序部署为 Istio 等服务网格的一部分时,可能会影响上报跨度的方式。
如果您希望看到 Istio 生成的span数据,但在 Jaeger UI 中看不到相关数据时,请查看 Istio 网站上的故障排除指南

运行后端服务的debug镜像

我们为每个 Jaeger 组件都提供了debug的镜像。
这些镜像已经在禁用优化的情况下编译了 delve 和相应的 Jaeger 组件。
当您运行这些镜像时,delve 会触发 Jaeger 组件作为其子进程的执行,并立即附加到它以开始新的调试会话并开始侦听 TCP 端口 12345 以获取远程连接。
然后,您可以使用 Visual Studio Code 或 GoLand 等 IDE 连接到此端口并远程连接它,并通过添加断点执行调试。

对于 Visual Studio Code,您需要在 Jaeger 源代码的本地克隆的根目录下进行以下配置:

  1. $ cat .vscode/launch.json
  2. {
  3. "version": "0.2.0",
  4. "configurations": [
  5. {
  6. "name": "Launch remote",
  7. "type": "go",
  8. "request": "attach",
  9. "mode": "remote",
  10. "remotePath": "",
  11. "port": 12345,
  12. "host": "127.0.0.1",
  13. "cwd": "${workspaceRoot}",
  14. }
  15. ]
  16. }