服务性能监控 (SPM)
此功能在 Jaeger UI 中以“监视器”选项卡的形式出现,其目的是帮助识别有趣的跟踪(例如,高 QPS、慢速或错误请求),而无需事先知道服务或操作名称。
它本质上是通过聚合跨度数据来生成 RED(请求、错误、持续时间)指标实现的。
潜在用例包括
- 在整个组织或请求链中已知的依赖服务上进行部署后健全性检查。
- 在收到问题警报时进行监控和根本原因分析。
- 为 Jaeger UI 的新用户提供更好的入门体验。
- 对 QPS、错误和延迟进行长期趋势分析。
- 容量规划。
UI 功能概述
“监视器”选项卡提供服务级聚合,以及服务内操作级聚合的请求速率、错误速率和持续时间(P95、P75 和 P50),也称为 RED 指标。
在操作级聚合中,“影响”指标(计算为延迟和请求速率的乘积)是另一个可以用来排除可能自然具有高延迟特征的操作(例如,每日批处理作业)的信号,或者相反,突出显示延迟排名较低但具有高 RPS(每秒请求数)的操作。
从这些聚合中,Jaeger UI 能够使用相关服务、操作和回溯时间段预填充跟踪搜索,从而缩小这些更有趣跟踪的搜索范围。
入门
在 Jaeger 存储库 中提供了本地可运行的设置,以及有关如何运行它的说明。
可以通过顶部菜单中的“监视器”选项卡访问此功能。
此演示包括 Microsim ; 一个微服务模拟器来生成跟踪数据。
如果希望手动生成跟踪,可以通过 docker 启动 示例应用程序:HotROD。确保在 docker run
命令中包含 --net monitor_backend
。
架构
Jaeger 用于监视器选项卡查询的 RED 指标是通过 OpenTelemetry 收集器 收集的跨度数据生成的,然后由其管道中配置的 SpanMetrics 连接器 组件进行聚合。
最后,这些指标由 OpenTelemetry 收集器(通过 Prometheus 导出器)导出到兼容 Prometheus 的指标存储中。
重要的是要强调,这是一个“只读”功能,因此它仅与 Jaeger 查询组件(和 All In One)相关。
派生时间序列
尽管这更多地属于 OpenTelemetry Collector 的范围,但了解 SpanMetrics Connector 在指标存储中生成的额外指标和时间序列有助于在部署 SPM 时进行容量规划。
请参考 Prometheus 文档 ,其中涵盖了指标名称、类型、标签和时间序列的概念;这些术语将在本节的其余部分中使用。
将创建两个指标名称
calls_total
- 类型:计数器
- 描述:统计总的跨度数量,包括错误跨度。调用计数通过
status_code
标签与错误区分。错误被识别为任何具有标签status_code = "STATUS_CODE_ERROR"
的时间序列。
[namespace_]duration_[units]
- 类型:直方图
- 描述:跨度持续时间/延迟的直方图。在幕后,Prometheus 直方图将创建多个时间序列。为了说明目的,假设没有配置命名空间并且单位是
milliseconds
duration_milliseconds_count
:直方图中所有桶的总数据点数量。duration_milliseconds_sum
:所有数据点值的总和。duration_milliseconds_bucket
:每个持续时间桶的n
个时间序列集合(其中n
是持续时间桶的数量),由le
(小于或等于)标签标识。对于每个跨度,le
最低且le >= 跨度持续时间
的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。默认值:https://127.0.0.1:9090。 - 可选:将
--prometheus.query.support-spanmetrics-connector=true
设置为明确启用 SpanMetrics Connector ,如果您打算使用它。这将在未来成为默认行为。
- 将
API
gRPC/Protobuf
以编程方式检索 RED 指标的推荐方法是通过 jaeger.api_v2.metrics.MetricsQueryService
gRPC 终结点,该终结点在 metricsquery.proto IDL 文件中定义。
HTTP JSON
由 Jaeger UI 的监控选项卡内部使用,以填充其可视化效果的指标。
参考 此 README 文件 ,以了解 HTTP API 的详细规范。
故障排除
检查 /metrics 终结点
/metrics
终结点可用于检查是否收到了特定服务的跨度。/metrics
终结点由管理端口提供服务。假设 Jaeger 全部合一和查询分别在名为 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 时看到这些计数器递增。
查看日志
如果上述指标存在于 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
而不是 calls
和 duration_bucket
,如下所示
PROMETHEUS_QUERY_NORMALIZE_CALLS=true
PROMETHEUS_QUERY_NORMALIZE_DURATION=true
检查 OpenTelemetry Collector 配置
如果有错误跨度出现在 Jaeger 中,但没有相应的错误指标
- 检查 Prometheus 中由 spanmetrics 连接器生成的原始指标(如上所述:
calls
、calls_total
、duration_bucket
等)是否包含跨度应属于的指标中的status.code
标签。 - 如果没有
status.code
标签,请检查 OpenTelemetry Collector 配置文件,特别是以下配置是否存在此标签由 Jaeger 用于确定请求是否出错。exclude_dimensions: ['status.code']
检查 OpenTelemetry Collector
如果上述 latency_bucket
和 calls_total
指标为空,则可能是 OpenTelemetry Collector 或其上游的任何组件配置错误。
在故障排除时需要问一些问题
- OpenTelemetry Collector 是否配置正确?
- OpenTelemetry Collector 是否可以连接到 Prometheus 服务器?
- 服务是否将跨度发送到 OpenTelemetry Collector?
监控选项卡中缺少服务/操作
如果监控选项卡中缺少服务/操作,但在 Jaeger 跟踪搜索中的服务和操作下拉菜单中可见,这通常是因为指标查询中使用了默认的 server
跨度类型。
您看不到的服务/操作可能来自非服务器跨度类型的跨度,例如客户端,更糟的是,unspecified
。因此,这是一个仪器数据质量问题,应设置仪器跨度类型。
默认使用 server
跨度类型的目的是避免分别在 server
和 client
跨度类型中对 ingress 和 egress 跨度进行双重计数。
执行指标查询时出现 403
如果日志包含类似以下的错误:failed executing metrics query: client_error: client error: 403
,则可能是 Prometheus 服务器正在期望一个 bearer token。
Jaeger 查询(和一体机)可以配置为通过 --prometheus.token-file
命令行参数(或 PROMETHEUS_TOKEN_FILE
环境变量)在指标查询中传递 bearer token,其值设置为包含 bearer token 的文件的路径。