原文链接:如何修复 Prometheus 中的“Context Deadline exceeded”错误 |西格诺兹 (signoz.io)

在 Prometheus 中遇到 “Context Deadline Exceeded” 错误?您并不孤单。当 Prometheus 无法及时从目标中抓取指标时,就会弹出这个讨厌的错误,从而导致数据出现差距和潜在的监控盲点。但别担心,本指南旨在帮助您了解它发生的原因,更重要的是,如何解决它。

了解 Prometheus 中的“Context Deadline exceeded”错误

什么是“Context Deadline exceeded”错误?

在 Prometheus 中,当服务器尝试从目标中抓取量度但时间已用完时,会发生“Context Deadline Exceeded”错误。Prometheus 有一个设定的时间限制(由 定义),如果它在 clock 用完之前没有得到数据,它会抛出这个错误并继续前进。scrape_timeout

在这里插入图片描述
Prometheus:Context Deadline exceeded 错误

对监控和数据收集的影响:当这些错误发生时,它们可能会产生重大影响:

  • 数据差距:错过抓取意味着您的指标存在差距,这可能导致仪表板和报告不完整。
  • 错过的警报:如果没有完整的数据,关键警报可能不会触发,从而不会注意到问题,直到为时已晚。
  • 故障排除增加:重复错误会导致诊断和修复问题的时间增加,而这本来是可以避免的。

解决“Context Deadline Exceeded”错误对于维护监控数据的完整性和确保可靠的系统监督至关重要。

为什么会发生 Context Deadline exceeded 错误

Prometheus 的工作原理是定期从目标中抓取指标。每个目标都有一个定义的 (检查频率) 和 (Prometheus 在放弃之前等待的时间)。如果目标未及时响应,则会收到“Context Deadline Exceeded”错误。scrape_interval``scrape_timeout

您通常会在以下几种情况下看到此错误:

  • 响应缓慢的目标:如果目标负载过重或优化不佳,则可能需要很长时间才能响应 Prometheus。
  • 网络问题:Prometheus 与其目标之间的延迟或数据包丢失可能会导致延迟,从而导致超时。
  • 超载的 Prometheus 服务器:如果 Prometheus 处理的任务过多或查询优化不佳,则可能无法跟上抓取间隔。

💡 暂停是为了防止 Prometheus 在单个目标上等待太久,确保它不会落后于报废其他目标。如果 Too Short 或 Targets 速度较慢,则会看到更多此类错误。scrape_timeout

Diagnosing Context Deadline Exceeded 错误

有效的故障排除始于正确的诊断。以下是识别和分析 Prometheus 设置中的 “Context Deadline Exceeded” 错误的方法:

  1. 检查 Prometheus UI:

    • 导航到 Prometheus Web 界面中的“目标”页面

      在这里插入图片描述
      导航到 Prometheus Web 界面中的 Targets 部分

    • 查找标记为“down”且错误消息包含“context deadline exceeded”的目标

      在这里插入图片描述
      在已关闭的目标中查找 ContextDeadline 错误

  2. 分析 Prometheus 日志:

    • 检查 Prometheus 服务器日志中是否存在包含“超出上下文截止时间”的条目
    • 记下受影响的目标和这些错误的频率
  3. 使用 Prometheus 调试端点:

    • 访问 Prometheus 服务器上的终端节点/debug/pprof

    • 查找卡在抓取操作中的 goroutine

      在这里插入图片描述
      访问 Prometheus 服务器上的 /debug/pprof 端点

      您会注意到很多数据,这些数据可能看起来难以阅读。

      在这里插入图片描述

      让我们一一解码:

      • 在配置文件捕获时有 31 个 goroutine 处于活动状态。

        在这里插入图片描述

        - 阻塞的 Goroutines(3 个实例)

        在这里插入图片描述

        - "3 @ …"表示 3 个不同的 goroutines 在这个特定的时间点正在执行相同的代码路径。

        • goroutines 卡在等待与网络相关的操作。
          • internal/poll.runtime_pollWait:正在等待文件描述符上的 I/O 事件。
          • internal/poll.FD.Read:从文件描述符(通常是网络套接字)读取数据。
          • *net/http.(connReader).Read*:表示此协程是 HTTP 请求处理程序的一部分,并且正在读取数据。
          • *net/http.(conn).serve*:这表明协程正在处理一个 HTTP 请求。
      • Discovery Manager Goroutines(2 个实例)

        在这里插入图片描述

        - 这些 goroutines 涉及 Prometheus 的发现管理器,该管理器处理目标的服务发现。

        • 该函数与发送目标发现更新有关。discovery/legacymanager.Manager.sender

      从上面,我们可以发现 goroutine 卡在等待与网络相关的操作。在尝试读取数据时暗示与网络相关的问题。

      💡

      要在超出上下文截止时间的情况下观察明显的变化,你通常会看到更多的 goroutine 卡在网络 I/O 中或等待超时条件,尤其是在 HTTP 客户端或抓取逻辑周围。将显示这些 goroutine 等待 or 函数的更多实例。goroutine profile``net/http``context

  4. 利用外部工具:

    • 使用 OR 等网络诊断工具检查连接。例如,向服务器发送 GET 请求会引发错误,暗示目标应用程序一端出现问题。ping``traceroute

      在这里插入图片描述
      检查目标服务器是否存在 Context Deadline Exceeded 错误

    • 使用 SigNoz 等监控工具更深入地了解您的基础设施。

通过系统地调查这些方面,您可以查明超时错误的根本原因并采取适当的措施。

配置 Prometheus 以防止超时错误

正确的配置是缓解 “Context Deadline Exceeded” 错误的关键。以下是优化 Prometheus 设置的基本步骤:

  1. 调整全局scrape_timeout设置:

    global:
      scrape_timeout: 15s
    

    如果您始终在多个目标中看到超时错误,请增加此值。

  2. 微调特定于作业的设置:

    scrape_configs:
      - job_name: 'example-job'
        scrape_interval: 30s
        scrape_timeout: 20s
    

    根据每个作业或目标组的特定需求定制这些设置。

  3. 实施重新标记:

    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: prometheus-proxy:9090
    

    使用重新标记来优化抓取配置,并在需要时通过代理路由请求。

  4. 平衡抓取频率和资源使用:避免设置过于激进的抓取间隔,这可能会使您的目标或 Prometheus 本身不堪重负。

Prometheus 配置最佳实践

要维护强大的 Prometheus 设置,请遵循以下最佳实践:

  1. 微调刮擦间隔和超时
    • Scrape Intervals:您确定 Prometheus 从目标中提取指标的频率。平衡是关键 — 设置得太短,您可能会使您的系统不堪重负;太长,您可能会错过关键数据。通常,15 到 30 秒的间隔效果很好,但对于速度较慢或不太关键的系统,请考虑使用更长的间隔以减少负载。scrape_interval
    • Scrape Timeouts(抓取超时):将 设置为 。这可确保如果目标速度较慢,Prometheus 不会陷入等待状态,并且可以继续执行下一个目标。例如,如果间隔为 15 秒,则 10-12 秒的超时通常是理想的。scrape_timeout``scrape_interval
  2. 使用 Relabeling 筛选指标
    • Prometheus 可以抓取大量数据,但并非所有数据都有用。
    • 使用重新标记规则在存储不必要的指标之前筛选掉这些指标。这减少了 Prometheus 的负载和遇到超时错误的机会。
  3. 使用 Service Discovery 分配负载
    • 利用服务发现来动态管理您的目标,尤其是在频繁变化的环境(如 Kubernetes)中。这使 Prometheus 能够有效地更新和管理抓取目标,从而减少系统过载的可能性。
  4. 实施高可用性 (HA)
    • 在高可用性设置中运行多个 Prometheus 实例有助于分配抓取负载并防止任何单个实例成为瓶颈。
    • HA 设置还提供冗余,确保即使一个实例出现故障,监控也会继续。

通过遵循这些准则,您可以创建一个更具弹性和效率的 Prometheus 监控系统。

优化目标系统以减少超时错误

虽然 Prometheus 配置至关重要,但优化目标系统可以显著减少超时错误的发生:

  1. 提高目标系统性能:
    • 为指标收集流程分配足够的资源
    • 优化生成指标的数据库查询或 API 调用
  2. 实现缓存机制:
    • 缓存经常访问的指标以减少抓取期间的计算时间
    • 使用 TSDB 或 Redis 等工具实现高效的指标缓存
  3. 优化网络连接:
    • 确保 Prometheus 和目标之间的低延迟网络路径
    • 考虑使用 Prometheus Federation 使抓取更接近目标
  4. 扩展复杂指标终端节点的资源:
    • 水平扩展公开资源密集型指标的服务
    • 考虑将复杂的指标终端节点分解为多个更简单的终端节点

通过解决目标系统上的性能瓶颈,您可以显著降低出现超时错误的可能性。

实施高级技术来缓解超时

对于更复杂的监控设置,请考虑以下高级技术:

  1. 使用 Prometheus Pushgateway:

    • 非常适合批处理作业或不可靠的目标
    • 允许目标将量度推送到中间网关
    push_config:
      endpoint: "http://pushgateway:9091/metrics"
    
  2. 实施断路器:

    • 使用 Hystrix 或 resilience4j 等工具处理临时故障
    • 防止由于目标无响应而导致级联失败
  3. 利用专业导出器:

    • 将指标收集处理工作分流到专用导出器
    • 使用高效的数据格式(如 Protocol Buffers)实现更快的序列化
  4. 采用负载平衡:

    • 在大容量目标的多个实例之间分配抓取请求
    • 使用基于 DNS 的负载均衡或专用负载均衡器

这些技术可以帮助您构建更具弹性的监控基础设施,能够处理复杂和大容量的指标收集场景。

针对 Context Deadline exceeded 错误的监控和警报

主动监控您的 Prometheus 设置对于维护其运行状况至关重要:

  1. 为持续超时错误设置警报:

    - alert: PersistentScrapeTimeout
      expr: rate(prometheus_target_scrapes_exceeded_sample_limit_total[5m]) > 0
      for: 15m
      labels:
        severity: warning
      annotations:
        summary: "Persistent scrape timeouts detected"
        description: "Target {{ $labels.instance }} is experiencing consistent scrape timeouts."
    
  2. 创建控制面板以可视化抓取性能:

    • 监控抓取持续时间趋势
    • 跟踪成功与失败的抓取数量
  3. 实施 SLO 以提高抓取成功率:

    • 设置抓取成功百分比的目标
    • 使用错误预算来指导改进工作
  4. 将超时错误与系统指标相关联:

    • 查找超时与 CPU、内存或网络使用情况之间的模式
    • 使用此数据为扩展决策或性能优化提供信息

通过为您的 Prometheus 基础设施实施全面的监控和警报,您可以在问题影响整体监控效果之前发现并解决问题。

使用 SigNoz 增强可观测性

超时问题(如 Prometheus 中的“Context Deadline Exceeded”错误)可能很难单独使用指标进行诊断。SigNoz 通过提供详细的跟踪来显示请求通过您的应用程序路径,从而增强您的可观测性堆栈。通过将 SigNoz 与 Prometheus 集成,您可以将指标数据与跟踪数据相关联,以快速确定超时发生的位置和发生的原因。

SigNoz 是一个开源可观测性平台,可提供对应用程序性能的深入洞察,从而更轻松地监控和排除复杂系统的故障。虽然 Prometheus 擅长收集指标并发出警报,但 SigNoz 通过强大的跟踪和日志记录功能扩展了这些功能,使您能够更全面地了解应用程序的行为。SigNoz 提供:

  1. 分布式跟踪,用于查明应用程序中的瓶颈
  2. 可以补充 Prometheus 数据的详细性能指标
  3. 用于将错误与系统事件相关联的日志管理
  4. 自定义控制面板,用于可视化 Prometheus 指标以及其他遥测数据

关键要点

  • Prometheus 中的“Context Deadline Exceeded”错误表示抓取操作超出了配置的超时限制。
  • 这些错误可能是由网络问题、目标系统性能问题或错误配置引起的。
  • 正确的诊断包括检查 Prometheus UI、日志和使用调试端点。
  • 优化 Prometheus 配置和目标系统对于防止超时错误至关重要。
  • 使用 Pushgateway 和实施断路器等高级技术可以提高可靠性。
  • 定期监控和提醒超时错误有助于保持健康的 Prometheus 设置。
  • 集成 SigNoz 等工具可以提供更深入的见解并补充 Prometheus 监控。

常见问题

Prometheus 中的默认抓取超时是多少?

Prometheus 中的默认抓取超时为 10 秒。但是,这可以在 Prometheus 配置文件中全局调整或按作业进行调整。

Context Deadline Exceeded 错误是否会影响数据准确性?

是的,这些错误可能会导致数据点不完整或缺失,这可能会影响指标的准确性,并可能影响警报和分析。

如何区分网络问题和目标性能问题?

使用网络诊断工具检查连接和延迟。如果网络指标正常,请调查目标系统资源和指标生成过程是否存在性能瓶颈。

是否可以为不同的目标设置不同的超时?

是的,Prometheus 允许您在配置文件的部分为每个作业设置不同的值。scrape_timeout``scrape_configs

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐