Ukraine flag 我们与我们在乌克兰的朋友和同事站在一起。如需支持乌克兰渡过难关,请访问此页面

故障排除

解决常见问题

版本  1.69 最新 转到最新的 2.x 版本

Jaeger 后端本身是一个分布式系统,由不同的组件组成,可能运行在许多主机上。可能会出现其中一个组件工作不正常的情况,导致跨度无法被处理或存储。当出现问题时,请务必检查此处列出的项目。

如果您在管道中使用了 OpenTelemetry Collector,请务必查阅其 故障排除指南external link - Jaeger 分布式追踪平台

验证采样策略

在检查其他事项之前,请务必确认正在使用的采样策略。对于开发目的或低流量场景,对每个跟踪进行采样很有用。在生产环境中,您可能希望使用较低的速率。在诊断为什么后端未收到跨度时,请务必将 SDK 配置为*对每个跟踪进行采样*。通常,采样策略可以通过环境变量设置。

OpenTelemetry SDK

如果您正在使用 OpenTelemetry SDK,它们应默认使用 parentbased_always_on 采样器,这实际上是 100% 采样。可以通过 OTEL_TRACES_SAMPLER 环境变量更改(请参阅文档external link - Jaeger 分布式追踪平台)。

使用 stdout Exporter

OpenTelemetry SDK 可以配置一个 Exporter,将记录的跨度打印到 stdout。启用它可以让您验证跨度是否确实被记录。

Jaeger SDK(已弃用)

如果您正在使用某个 Jaeger SDK,它们默认使用概率采样策略,跟踪记录的几率为 1/1000。可以通过设置以下环境变量更改策略

JAEGER_SAMPLER_TYPE=const
JAEGER_SAMPLER_PARAM=1

例如,使用 Jaeger SDK for Java 时,创建跟踪器时通常会通过被 instrumented 应用程序提供的日志工具打印出策略

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

远程采样

Jaeger 后端支持远程采样,即集中配置采样策略并使其可供 SDK 使用。部分(但非全部)OpenTelemetry SDK 支持远程采样,通常通过扩展实现(详见迁移到 OpenTelemetry)。

如果您怀疑远程采样工作不正常,请尝试以下步骤

  1. 确保 SDK 实际配置为使用远程采样,指向正确的采样服务地址(参阅API),并且该地址可从您应用程序的网络命名空间访问。
  2. 验证服务器是否为您的服务返回了适当的采样策略
    $ curl "jaeger-collector:14268/api/sampling?service=foobar"
    {"strategyType":"PROBABILISTIC","probabilisticSampling":{"samplingRate":0.001}}

网络命名空间

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

  • 未将适当的端口暴露在容器外部。例如,Collector 可能在容器网络命名空间内监听 :4317,但该端口无法从外部访问。
  • 未使 jaeger-collector 的主机名可从应用程序的网络命名空间访问。例如,如果您在 Docker 中单独的容器中运行您的应用程序和 Jaeger 后端,它们要么需要在同一个命名空间中,要么需要使用 docker 命令的 --link 选项为应用程序的容器授予访问 Jaeger 后端的权限。

增加后端组件的日志级别

将日志级别设置为 debug 时,Jaeger 提供有用的调试信息。jaeger-collector 会记录接收到的每个批次和存储在永久存储中的每个跨度的信息。

jaeger-collector 端,指定标志 --log-level=debug 时预期的日志条目如下

{"level":"debug","ts":1544458854.5406284,"caller":"app/span_handler.go:90","msg":"Span batch processed by the collector.","ok":true}
{"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"}
{"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"}
{"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"}

检查 /metrics 端点

对于无法或不宜增加 Jaeger 后端日志级别的情况,可以使用 /metrics 端点来检查是否接收到特定服务的跨度。/metrics 端点通过 admin 端口提供服务,该端口因每个二进制文件而异(参阅部署)。假设 jaeger-collector 在主机名为 jaeger-collector 的主机上可用,以下是获取指标的示例 curl 调用

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

以下指标特别值得关注

jaeger_collector_spans_received
jaeger_collector_spans_saved_by_svc
jaeger_collector_traces_received
jaeger_collector_traces_saved_by_svc

前两个指标对于同一服务应具有相似的值。同样,两个 traces 指标也应具有相似的值。例如,这是一个按预期工作的设置示例

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

Istio:跨度丢失

当您将应用程序部署为 Istio 等服务网格的一部分时,活动部件的数量会显著增加,这可能会影响跨度的报告方式(以及报告哪些跨度)。如果您期望看到 Istio 生成的跨度但它们未在 Jaeger UI 中显示,请查看 Istio 网站上的故障排除指南external link - Jaeger 分布式追踪平台

运行后端组件的调试镜像

我们为每个 Jaeger 组件提供了调试镜像。这些镜像包含 delveexternal link - Jaeger 分布式追踪平台 以及相应的 Jaeger 组件,这些组件编译时禁用了优化。当您运行这些镜像时,delve 会触发 Jaeger 组件作为其子进程执行,并立即附加到它以启动新的调试会话并开始监听 TCP 端口 12345 以进行远程连接。然后,您可以使用您的 IDE,如 Visual Studio Codeexternal link - Jaeger 分布式追踪平台GoLandexternal link - Jaeger 分布式追踪平台 连接到此端口并进行远程附加,并通过添加断点来执行调试external link - Jaeger 分布式追踪平台

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

$ cat .vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch remote",
            "type": "go",
            "request": "attach",
            "mode": "remote",
            "remotePath": "",
            "port": 12345,
            "host": "127.0.0.1",
            "cwd": "${workspaceRoot}",
        }
    ]
}