4. Target 抓取生命周期:从服务发现到抓取、抓取协议(HTTP/HTTPS)、抓取超时与重试机制
Prometheus 通过 Pull 模式主动从 Target 拉取指标数据。一个完整的抓取生命周期涉及服务发现、目标实例化、协议协商、数据拉取、超时控制与重试等多个阶段。理解这一生命周期是诊断抓取故障、优化采集性能的基础。
4.1 抓取生命周期总览
从服务发现到指标入库,一个 Target 的抓取过程可划分为以下关键阶段:
- 服务发现:通过配置的服务发现机制(如 Kubernetes、Consul、DNS、文件发现)获取目标列表。
- 目标实例化:将发现的目标转换为
__address__、__metrics_path__、__scheme__等内部标签,并应用 relabel 规则。 - 健康检查与协议协商:根据
scheme(HTTP/HTTPS)建立连接,可选 TLS 握手。 - 指标拉取:向
<scheme>://<address><metrics_path>发送 GET 请求,读取响应体。 - 超时控制:在
scrape_timeout内完成 DNS 解析、连接、TLS 握手、请求发送和响应读取。 - 数据解析与重试:解析响应体为 Prometheus 文本格式,若失败则根据配置决定是否重试。
- 样本入库:将解析后的样本追加到 TSDB 的 Head 块。
4.2 抓取协议:HTTP 与 HTTPS
Prometheus 使用标准 HTTP/HTTPS 协议与 Target 通信。协议选择由 scheme 配置项控制,默认值为 http。
| 配置项 | 默认值 | 说明 |
|---|---|---|
scheme |
http |
可选 http 或 https,决定使用明文还是 TLS 加密连接 |
tls_config |
空 | HTTPS 模式下可配置 CA 证书、客户端证书、跳过验证等参数 |
metrics_path |
/metrics |
抓取路径,与 scheme 和 address 拼接为完整 URL |
协议选择最佳实践:
- 生产环境建议使用 HTTPS 加密传输,防止指标数据在传输过程中被窃听或篡改。
- 使用 HTTPS 时务必配置
tls_config中的ca_file或insecure_skip_verify: false,避免中间人攻击。 - 对于 Kubernetes 环境,Kubelet 的 /metrics/cadvisor 端点通常使用 HTTPS,需配置正确的 CA 证书。
4.3 抓取超时机制
超时控制是抓取生命周期中最关键的故障防护机制。Prometheus 通过 scrape_timeout 参数控制单次抓取的最大耗时。
4.3.1 超时配置与默认值
| 参数 | 默认值 | 作用范围 |
|---|---|---|
scrape_timeout |
10s |
单次抓取的总超时(包括 DNS、TCP、TLS、请求、响应) |
scrape_interval |
1m |
两次抓取之间的间隔,必须大于 scrape_timeout |
重要约束:scrape_timeout 必须小于 scrape_interval,否则会导致抓取队列积压、样本时间戳混乱。官方建议 scrape_timeout 不超过 scrape_interval 的 80%。
4.3.2 超时发生的阶段与表现
超时可能发生在以下任意阶段,每个阶段的超时表现不同:
- DNS 解析超时:无法解析 Target 主机名,日志中出现
dial tcp: lookup xxx: i/o timeout。 - TCP 连接超时:无法建立 TCP 连接,日志中出现
connect: connection timed out。 - TLS 握手超时:HTTPS 模式下 TLS 协商失败,日志中出现
tls: handshake timeout。 - 请求发送超时:数据发送阶段卡住,通常由 Target 端负载过高或网络拥塞导致。
- 响应读取超时:Target 返回数据过慢或数据量过大,导致读取时间超过剩余超时窗口。
4.4 重试机制
Prometheus 的重试机制相对简单,旨在处理瞬态故障而非持续性问题。
4.4.1 重试配置
| 参数 | 默认值 | 说明 |
|---|---|---|
scrape_retries |
0 |
抓取失败后的重试次数,0 表示不重试 |
scrape_retry_delay |
5s |
重试之间的等待间隔 |
4.4.2 重试触发条件
重试仅在以下场景触发:
- HTTP 状态码非 200:如返回 500、503 等服务器错误。
- 响应体解析失败:返回的数据不是有效的 Prometheus 文本格式或 Protobuf 格式。
- 网络层错误:如连接重置、TLS 证书错误等。
以下场景不会触发重试:
- 超时:超时后直接标记为失败,不重试。
- HTTP 4xx 错误:如 401、403、404,表示客户端错误,重试无意义。
- 样本入库失败:解析成功但写入 TSDB 失败。
重试策略建议:
- 对于关键 Target(如 Kubelet、etcd),建议设置
scrape_retries: 1以容忍瞬态网络抖动。 - 避免设置过大的重试次数(如 >3),否则会加剧 Target 端负载并延迟后续抓取。
- 重试次数过多时,可通过
prometheus_target_scrapes_exceeded_sample_limit_total等指标监控抓取质量。
4.5 抓取生命周期相关指标
Prometheus 自身暴露了丰富的指标用于监控抓取过程,以下是核心指标:
| 指标名称 | 类型 | 说明 |
|---|---|---|
prometheus_target_scrapes_total |
Counter | 抓取总次数,按 scrape_job、instance 标签区分 |
prometheus_target_scrapes_failed_total |
Counter | 抓取失败次数(包括超时、HTTP 错误、解析错误) |
prometheus_target_scrapes_timeout_total |
Counter | 抓取超时次数 |
prometheus_target_scrapes_exceeded_sample_limit_total |
Counter | 超过样本数限制的次数 |
prometheus_target_scrape_duration_seconds |
Gauge | 最近一次抓取的耗时(秒) |
prometheus_target_scrape_pool_sync_total |
Counter | 抓取池同步次数,反映服务发现更新频率 |
4.6 常见故障排查清单
当 Target 抓取出现异常时,可按以下步骤排查:
- 检查 Target 状态页:Prometheus Web UI 的 /targets 页面会显示每个 Target 的状态(UP/DOWN)和上次错误信息。
- 查看 Prometheus 日志:使用
--log.level=debug启动可获取详细的抓取日志。 - 验证网络连通性:从 Prometheus 节点直接 curl 目标 URL,确认是否可达。
- 检查超时配置:确认
scrape_timeout是否过小,特别是对于返回大量指标的 Target。 - 检查样本数限制:查看
prometheus_target_scrapes_exceeded_sample_limit_total是否增长,必要时调整sample_limit。 - 检查 TLS 配置:HTTPS 模式下确认证书是否有效、是否过期、是否被正确信任。
- 检查重试配置:确认
scrape_retries是否合理,避免因重试导致抓取间隔被压缩。
快速诊断命令示例:
# 从 Prometheus 节点手动测试抓取
curl -v --connect-timeout 5 --max-time 10 http://target-ip:8080/metrics
# 检查 Prometheus 自身抓取指标
curl -s http://localhost:9090/metrics | grep -E "prometheus_target_scrapes_(total|failed|timeout)"
# 查看特定 job 的抓取耗时分布
curl -s http://localhost:9090/api/v1/query?query=prometheus_target_scrape_duration_seconds{job="kubernetes-nodes"}