4. 指标采集故障:Prometheus/Tempo 采集器离线、指标延迟、数据空洞的排查方法

指标采集是灰度发布准入判断的数据基础。当 Prometheus 或 Tempo 采集器出现离线、指标延迟或数据空洞时,门禁系统将无法获取实时指标,导致误判或准入阻塞。本节系统梳理三类采集故障的根因定位与恢复流程。

4.1 故障分类与影响矩阵

采集故障按现象可分为三类,其影响范围与紧急程度不同:

故障类型 现象 典型根因 对门禁影响 紧急程度
采集器离线 Target Up = 0,HTTP 探针超时 进程崩溃、网络分区、配置错误 门禁完全无法获取指标,准入决策阻塞 P0
指标延迟 时间戳滞后 > 2× scrape_interval 存储写入瓶颈、远程写积压、时钟偏移 门禁使用过期数据,可能误放或误拦 P1
数据空洞 时间序列出现连续缺失 > 3 个采样周期 采集器重启、网络抖动、relabel 过滤 门禁无法计算窗口聚合,降级为默认策略 P1
排查优先级: 先确认采集器是否在线(Up == 1),再检查指标新鲜度(up_to_date),最后分析数据连续性(stale NaN 比例)。按此顺序可快速缩小范围。

4.2 采集器离线排查步骤

采集器离线是最严重的故障,需按以下步骤逐层排查:

  1. 确认离线范围: 在 Prometheus 的 /targets 页面查看所有 Target 状态,区分是单个 Job 离线还是全局离线。
  2. 检查进程存活: 登录采集器节点,执行 systemctl status prometheus 或 ps aux | grep prometheus,确认进程是否运行。
  3. 查看日志: 使用 journalctl -u prometheus --since "5 min ago" 或直接查看 /var/log/prometheus/prometheus.log,搜索 error、panic、OOM 等关键词。
  4. 验证网络连通: 从采集器向目标端点执行 curl -v http://target:9100/metrics,确认是否可达。注意检查防火墙规则、DNS 解析、TLS 证书。
  5. 检查资源限制: 使用 free -h、df -h、top 确认内存、磁盘、CPU 是否耗尽。Prometheus 在磁盘写满时会自动退出。
  6. 检查配置变更: 对比最近一次配置变更记录,确认 scrape_configs 中的 targets 地址、端口、路径是否正确。
快速恢复命令: 若确认是进程崩溃,可执行 systemctl restart prometheus 尝试恢复。但需注意重启后 WAL 回放可能导致短暂延迟,建议先备份 data/ 目录。

4.3 指标延迟排查方法

指标延迟表现为查询结果的时间戳远小于当前时间。排查需从采集、存储、查询三个环节入手:

排查环节 关键指标 正常阈值 异常处理
采集端 prometheus_target_scrape_duration_seconds < scrape_interval × 80% 增加 scrape_timeout 或拆分 Job
存储端 prometheus_tsdb_head_series、prometheus_tsdb_wal_storage_size_bytes WAL 大小 < 1GB 调整 --storage.tsdb.retention.time 或扩容磁盘
远程写 prometheus_remote_storage_queue_highest_sent_timestamp_seconds 与当前时间差 < 30s 检查网络带宽、Thanos Receiver 负载
查询端 prometheus_engine_query_duration_seconds 分位数 p99 < 1s 优化 PromQL 或增加查询并发

典型延迟场景: 当 prometheus_tsdb_head_series 超过 1000 万时,TSDB 的 compaction 和 memory-mapped chunks 操作会显著变慢,导致写入延迟。此时应减少采集目标数或增加 --storage.tsdb.min-block-duration。

4.4 数据空洞排查方法

数据空洞指时间序列在连续时间窗口内缺失采样点。排查需区分是采集端未产生数据,还是存储端丢失数据:

  • 采集端原因:
    • Target 临时不可用(重启、滚动更新)
    • scrape_timeout 过短导致采样失败
    • relabel_config 过滤掉了某些指标
    • 采集器自身 GC 停顿导致错过采样周期
  • 存储端原因:
    • WAL 损坏导致数据无法回放
    • 磁盘 I/O 瓶颈导致写入失败
    • retention 策略误删了未压缩的 block
    • 远程写失败且本地缓存被清理

排查命令:

# 检查特定指标的空洞情况
# 查询最近 1 小时每个采样点的数量,若 count < 预期值则存在空洞
count_over_time(up{job="my-service"}[1h])

# 查看采集器日志中的 scrape 失败记录
grep "scrape failed" /var/log/prometheus/prometheus.log | tail -20

# 检查 TSDB block 完整性
ls -la /data/prometheus/tsdb/ | grep -E "^d" | wc -l
# 正常应有连续的时间范围 block,若出现 gap 则说明数据丢失
注意: 数据空洞可能导致门禁的滑动窗口聚合(如 5m 平均错误率)计算不准确。建议在门禁规则中增加 absent() 或 count() 校验,当采样点数量低于阈值时自动降级为“数据不足,跳过准入”。

4.5 采集故障排查流程图

以下流程图汇总了从发现故障到恢复的完整排查路径:

采集故障排查流程图 发现采集异常 Target Up == 1? 否 采集器离线排查 是 检查指标新鲜度 1. 检查进程/日志 2. 检查网络/资源 重启或回滚配置 时间戳延迟? 是 指标延迟排查 检查存储/远程写 扩容或优化配置 否 数据空洞? 是 数据空洞排查 检查 relabel/网络 修复 WAL/block 恢复并验证

4.6 预防与自愈措施

为减少采集故障对灰度发布门禁的影响,建议实施以下预防措施:

  • 采集器高可用: 部署至少 2 个 Prometheus 实例,使用 hashmod 或 consul_sd_config 实现负载分担,避免单点故障。
  • 指标健康监控: 对采集器自身设置告警规则:
    # 采集器离线告警
    - alert: PrometheusTargetDown
      expr: up == 0
      for: 1m
      labels: { severity: critical }
    
    # 指标延迟告警
    - alert: PrometheusScrapeDelay
      expr: time() - prometheus_target_last_scrape_duration_seconds > 120
      for: 2m
      labels: { severity: warning }
  • 数据空洞检测: 在门禁准入规则中增加数据完整性校验,例如:
    # 检查最近 5 分钟采样点数量是否足够
    count_over_time(http_requests_total{job="my-service"}[5m]) < 3
  • 自动恢复脚本: 编写 systemd 自动重启策略,设置 Restart=always 和 RestartSec=10,配合 ulimit 限制防止 OOM。
最佳实践: 在灰度发布门禁系统中,建议将采集器健康状态作为准入前置条件。当采集器离线或指标延迟超过阈值时,自动暂停灰度发布并通知 SRE 介入,避免基于错误数据做出准入决策。