根本原因是prometheus的scrape_interval配置过长,它决定了指标从产生到可查的最小时间窗口;例如设为30s时,hyperf上报的指标最多延迟30秒才进入tsdb,grafana查询自然滞后,且该延迟占总延迟主导地位。

Hyperf项目监控看板数据延迟,根本原因不是Hyperf本身,而是Prometheus的scrape_interval配置太长——它决定了指标从产生到被采集、存储、可查的最小时间窗口。
为什么改scrape_interval能缓解延迟
Prometheus是Pull模型,所有指标必须等下一次抓取周期才进入TSDB。比如scrape_interval: 30s,意味着Hyperf上报的hyperf_db_query_duration_ms最多要等30秒才出现在Prometheus里,Grafana查询自然延迟。这不是网络或渲染问题,是采集节奏卡死的硬性约束。
- Hyperf的metric上报是即时的(HTTP响应即完成),但Prometheus不主动“知道”有新数据
- 延迟 =
scrape_interval+ 网络RTT + 解析开销,其中scrape_interval占主导 - 即使Grafana刷新间隔设为5s,底层数据源没更新,看板也只会重复显示旧值
哪些job该调、哪些不该动
不能全局统一缩短scrape_interval。高频抓取会直接压垮目标服务和Prometheus自身,尤其对PHP-FPM类短连接服务更敏感。
- 优先调
job_name: 'hyperf-app'这类业务服务:从30s → 15s 或 10s(需验证目标QPS承载) - 禁用对
node_exporter或mysqld_exporter盲目降频:它们是常驻进程,15s是安全底线 -
pushgatewayjob必须单独设:它本质是缓冲区,scrape_interval应 ≥ 业务方打点频率,否则漏数据;常见配30s–60s - 静态发现的
static_configs目标若数量超200个,降低scrape_interval反而引发并发雪崩,先做relabel过滤
scrape_timeout必须同步调大
默认scrape_timeout: 10s在scrape_interval缩到10s时极容易超时——抓取还没完成,下一轮调度已触发,导致target持续DOWN状态。
- 规则:把
scrape_timeout设为scrape_interval的70%~80%,例如interval=10s → timeout=7s - 如果目标是Kubernetes Pod且启用了liveness probe,timeout过大会干扰健康检查,此时宁可保持10s timeout、把interval拉回15s
- 超时错误在Prometheus UI的
Status > Targets页明确显示为context deadline exceeded,不是网络不通
真正影响看板体验的隐藏因素
改完scrape_interval后看板仍有卡顿,大概率是Grafana没配对:
- Grafana面板的
Min step(最小时间步长)必须 ≤ Prometheus的scrape_interval,否则自动插值,显示“平滑曲线”但非真实点 - 使用
rate()类函数时,区间长度(如rate(http_requests_total[5m]))应 ≥ 4×scrape_interval,否则计算结果稀疏抖动 - Hyperf的
hyperf_db_query_duration_ms是直方图指标,直接查sum无意义,要用histogram_quantile(0.95, sum(rate(hyperf_db_query_duration_ms_bucket[5m])) by (le))
最易被忽略的是:Hyperf应用自身metric暴露端点(如/metrics)的响应耗时。如果PHP处理一个/metrics请求要200ms,那就算scrape_interval设成5s,实际有效采集间隔也接近205s——得先用ab或hey压测暴露端点性能。











