服务性能监控 (SPM)
该功能在 Jaeger UI 中以“监控”标签页的形式展现,其目的是帮助用户无需预先知道服务或操作名称即可识别出有趣的追踪(例如高 QPS、慢请求或错误请求)。
它主要是通过聚合 Span 数据来生成 RED(请求、错误、持续时间)指标来实现的。
潜在的使用场景包括
- 部署后在组织内或请求链中已知的依赖服务上进行健全性检查。
- 当收到问题警报时进行监控和根本原因分析。
- 为 Jaeger UI 新用户提供更好的入门体验。
- 对 QPS、错误和延迟进行长期趋势分析。
- 容量规划。
UI 功能概览
“监控”标签页提供了服务级别的聚合,以及服务内的操作级别聚合,包括请求率、错误率和持续时间(P95、P75 和 P50),这些也称为 RED 指标。
在操作级别聚合中,还有一个“影响”指标,它被计算为延迟和请求率的乘积,这个信号可以用来排除那些自然具有高延迟特征的操作,比如每日批处理作业,或者相反地突出那些在延迟排名中靠后但 RPS(每秒请求数)很高的操作。
基于这些聚合数据,Jaeger UI 能够预先填充追踪搜索的相关服务、操作和回溯时间段,从而缩小对这些更具价值的追踪的搜索范围。
入门
Jaeger 仓库 中提供了一个可在本地运行的设置,其中包含运行说明。
该功能可以通过顶部菜单栏的“监控”标签页访问。
这个演示包含了 Microsim ;一个用于生成追踪数据的微服务模拟器。
如果倾向于手动生成追踪,可以通过 docker 启动示例应用:HotROD。请务必在 docker run
命令中包含 --net monitor_backend
。
架构
Jaeger 为监控标签页查询的 RED 指标,是 OpenTelemetry Collector 收集的 Span 数据经过其管道中配置的 SpanMetrics Connector 组件聚合后得到的结果。
这些指标最终由 OpenTelemetry Collector(通过 Prometheus Exporter)导出到与 Prometheus 兼容的指标存储中。
重要的是要强调,这是一个“只读”功能,因此仅与 Jaeger Query 组件(以及 All In One)相关。
派生时间序列
虽然这更属于 OpenTelemetry Collector 的范畴,但了解 SpanMetrics Connector 将在指标存储中生成的额外指标和时间序列对于部署 SPM 时的容量规划非常重要。
请参阅 Prometheus 文档 ,了解指标名称、类型、标签和时间序列的概念;这些术语将在本节的其余部分中使用。
将创建两个指标名称
calls_total
- 类型: counter
- 描述: 统计 Span 的总数,包括错误 Span。通过
status_code
标签区分调用次数和错误。错误是指任何带有标签status_code = "STATUS_CODE_ERROR"
的时间序列。
[命名空间_]duration_[单位]
- 类型: histogram
- 描述: Span 持续时间/延迟的直方图。在底层,Prometheus 直方图将创建多个时间序列。为了便于说明,假设未配置命名空间且单位为
milliseconds
duration_milliseconds_count
: 直方图中所有桶的总数据点数。duration_milliseconds_sum
: 所有数据点值的总和。duration_milliseconds_bucket
: 每个持续时间桶的一组n
个时间序列(其中n
是持续时间桶的数量),由le
(小于或等于)标签标识。对于每个 Span,具有最低le
且le >= span duration
的duration_milliseconds_bucket
计数器将递增。
以下公式旨在为创建的新时间序列数量提供一些指导
num_status_codes * num_span_kinds * (1 + num_latency_buckets) * num_operations
Where:
num_status_codes = 3 max (typically 2: ok/error)
num_span_kinds = 6 max (typically 2: client/server)
num_latency_buckets = 17 default
代入这些数字,假设采用默认配置
max = 324 * num_operations
typical = 72 * num_operations
注意
配置
启用 SPM
启用 SPM 功能需要以下配置
- Jaeger UI
- Jaeger Query
- 将环境变量
METRICS_STORAGE_TYPE
设置为prometheus
。 - 可选:将
--prometheus.server-url
(或环境变量PROMETHEUS_SERVER_URL
)设置为 Prometheus 服务器的 URL。默认值:http://localhost:9090。
- 将环境变量
API
gRPC/Protobuf
推荐以编程方式检索 RED 指标的方法是通过 metricsquery.proto IDL 文件中定义的 jaeger.api_v2.metrics.MetricsQueryService
gRPC 端点。
HTTP JSON
供 Jaeger UI 的监控标签页内部使用,用于填充可视化所需的指标。
有关 HTTP API 的详细规范,请参阅 此 README 文件 。
故障排除
检查 /metrics 端点
/metrics
端点可用于检查是否收到了特定服务的 Span。/metrics
端点由管理端口提供服务。假设 Jaeger all-in-one 和 query 分别在名为 all-in-one
和 jaeger-query
的主机下可用,以下是获取指标的示例 curl
调用:
$ curl http://all-in-one:14269/metrics
$ curl http://jaeger-query:16687/metrics
以下指标最为重要
# all-in-one
jaeger_requests_total
jaeger_latency_bucket
# jaeger-query
jaeger_query_requests_total
jaeger_query_latency_bucket
每个指标都将为以下每个操作带有一个标签
get_call_rates
get_error_rates
get_latencies
get_min_step_duration
如果一切按预期工作,带有标签 result="ok"
的指标应该在递增,而 result="err"
则保持静态。例如
jaeger_query_requests_total{operation="get_call_rates",result="ok"} 18
jaeger_query_requests_total{operation="get_error_rates",result="ok"} 18
jaeger_query_requests_total{operation="get_latencies",result="ok"} 36
jaeger_query_latency_bucket{operation="get_call_rates",result="ok",le="0.005"} 5
jaeger_query_latency_bucket{operation="get_call_rates",result="ok",le="0.01"} 13
jaeger_query_latency_bucket{operation="get_call_rates",result="ok",le="0.025"} 18
jaeger_query_latency_bucket{operation="get_error_rates",result="ok",le="0.005"} 7
jaeger_query_latency_bucket{operation="get_error_rates",result="ok",le="0.01"} 13
jaeger_query_latency_bucket{operation="get_error_rates",result="ok",le="0.025"} 18
jaeger_query_latency_bucket{operation="get_latencies",result="ok",le="0.005"} 7
jaeger_query_latency_bucket{operation="get_latencies",result="ok",le="0.01"} 25
jaeger_query_latency_bucket{operation="get_latencies",result="ok",le="0.025"} 36
如果从 Prometheus 读取指标时出现问题,例如无法连接到 Prometheus 服务器,那么带有标签 result="err"
的指标将会递增。例如
jaeger_query_requests_total{operation="get_call_rates",result="err"} 4
jaeger_query_requests_total{operation="get_error_rates",result="err"} 4
jaeger_query_requests_total{operation="get_latencies",result="err"} 8
此时,检查日志将为定位问题的根本原因提供更多信息。
查询 Prometheus
即使上述 Jaeger 指标表明已成功从 Prometheus 读取数据,图表仍可能显示为空。在这种情况下,请直接在 Prometheus 中查询以下任何指标:
duration_bucket
duration_milliseconds_bucket
duration_seconds_bucket
calls
calls_total
随着服务向 OpenTelemetry Collector 发送 Span,您应该看到这些计数器在增加。
查看日志
如果上述指标在 Prometheus 中存在,但未显示在“监控”标签页中,则表明 Jaeger 期望在 Prometheus 中看到的指标与实际可用的指标之间存在差异。
可以通过设置以下环境变量来提高日志级别以确认此问题
LOG_LEVEL=debug
输出类似于以下的日志
{
"level": "debug",
"ts": 1688042343.4464543,
"caller": "metricsstore/reader.go:245",
"msg": "Prometheus query results",
"results": "",
"query": "sum(rate(calls{service_name =~ \"driver\", span_kind =~ \"SPAN_KIND_SERVER\"}[10m])) by (service_name,span_name)",
"range":
{
"Start": "2023-06-29T12:34:03.081Z",
"End": "2023-06-29T12:39:03.081Z",
"Step": 60000000000
}
}
在此示例中,假设 OpenTelemetry Collector 的 prometheusexporter
引入了一项重大更改,它为计数器指标和直方图指标中的持续时间单位附加了 _total
后缀(例如 duration_milliseconds_bucket
)。正如我们发现的,Jaeger 正在查找 calls
(和 duration_bucket
)指标名称,而 OpenTelemetry Collector 则写入 calls_total
(和 duration_milliseconds_bucket
)。
在这种特定情况下,解决方案是设置环境变量,告诉 Jaeger 规范化指标名称,以便它知道去查找 calls_total
和 duration_milliseconds_bucket
,而不是原来的名称,如下所示
PROMETHEUS_QUERY_NORMALIZE_CALLS=true
PROMETHEUS_QUERY_NORMALIZE_DURATION=true
检查 OpenTelemetry Collector 配置
如果在 Jaeger 中出现了错误 Span,但没有相应的错误指标
- 检查 spanmetrics connector 在 Prometheus 中生成的原始指标(如上面列出的:
calls
,calls_total
,duration_bucket
等)是否包含 Span 所属指标的status.code
标签。 - 如果没有
status.code
标签,请检查 OpenTelemetry Collector 配置文件,特别是是否存在以下配置Jaeger 使用此标签来判断请求是否出错。exclude_dimensions: ['status.code']
检查 OpenTelemetry Collector
如果上述 latency_bucket
和 calls_total
指标为空,则可能是 OpenTelemetry Collector 或其上游的任何配置错误。
故障排除时需要考虑的问题有
- OpenTelemetry Collector 配置是否正确?
- OpenTelemetry Collector 是否可以访问 Prometheus 服务器?
- 服务是否将 Span 发送到 OpenTelemetry Collector?
监控标签页中缺少服务/操作
如果服务/操作未显示在“监控”标签页中,但在 Jaeger 追踪搜索的服务和操作下拉菜单中可见,常见的原因是指标查询中使用了默认的 server
Span 类型。
您未看到的服务/操作可能来自非 server
Span 类型的 Span,例如 client
或更糟的是 unspecified
。因此,这是一个埋点数据质量问题,埋点应该设置 Span 类型。
默认使用 server
Span 类型的原因是为了避免在 server
和 client
Span 类型中分别对入口和出口 Span 进行重复计数。
执行指标查询时出现 403 错误
如果日志中包含类似:failed executing metrics query: client_error: client error: 403
的错误,则可能是 Prometheus 服务器需要 bearer token。
Jaeger Query(和 all-in-one)可以通过 --prometheus.token-file
命令行参数(或 PROMETHEUS_TOKEN_FILE
环境变量)配置在指标查询中传递 bearer token,其值设置为包含 bearer token 的文件路径。