Prometheus+Grafana能否获取匹配AWS的准确RPM指标
监控方案问题排查与落地
目标
- 基于Grafana + Prometheus实现两类核心指标的可观测:RPM(每分钟请求数)、服务运行时长
当前部署架构
整条指标采集链路用到的组件如下:
django-prometheus -> 负责生成并暴露服务侧指标 fluent-bit -> 每15秒抓取一次Django暴露的指标,推送到Prometheus prometheus -> 在K8s集群上通过Prometheus Operator部署,共运行2个分片
问题描述
将Grafana看板展示的请求指标与AWS目标组请求指标做对比时,两边数值始终无法匹配。目前已经尝试过以下三组PromQL表达式计算请求相关指标:
sum by(service) (irate(django_http_requests_before_middlewares_total{namespace="name"}[5m])) sum by(service) (increase(django_http_requests_before_middlewares_total{namespace="name"}[5m])) sum by(service) (rate(django_http_requests_before_middlewares_total{namespace="name"}[5m]))
涉及的核心指标属性:
django_http_requests_before_middlewares_total:Counter(计数器)类型指标 由于指标携带container_id、service_name、namespace三个唯一维度,正常运行下计数器不会发生重置
核心疑问
是否可以在Grafana上搭建与AWS目标组数值一致的监控看板,获取准确的每分钟请求数?理论上increase函数可以满足计算需求,但该函数持续计算差值的逻辑疑似是结果不准的原因,需要可行的解决方案。
可行解决方案
数值不匹配是多个问题叠加导致的,按以下步骤调整即可把误差控制在合理范围:
- 先排查基础配置错误
- 解决Prometheus双分片重复计数问题:2个分片如果未配置按抓取目标分片,会同时存储全量服务指标,直接sum会把同一份指标计算两次,结果直接翻倍。查询时需要先通过
sum without (shard, replica)消去分片、副本维度的重复值,确保每个container_id对应的指标只被计算一次。 - 对齐统计口径:AWS目标组默认会把健康检查请求计入请求数,如果你在django-prometheus中配置了排除
/health等健康检查路径,要么在AWS侧过滤掉健康检查指标,要么在PromQL中把健康检查路径的指标加回来,两边统计的请求范围必须一致。
- 解决Prometheus双分片重复计数问题:2个分片如果未配置按抓取目标分片,会同时存储全量服务指标,直接sum会把同一份指标计算两次,结果直接翻倍。查询时需要先通过
- 修正PromQL计算逻辑
你之前用的查询语句本身和RPM的定义不匹配:rate/irate返回的是每秒平均请求数,直接拿来和每分钟的RPM对比,数值会差60倍increase(<counter>[5m])返回的是5分钟窗口内的总请求数,拿来和单分钟统计值对比,数值会高3-5倍irate取窗口内最后两个样本计算瞬时速率,对流量突刺非常敏感,和AWS固定窗口聚合的统计逻辑偏差极大,不适合做RPM统计
准确的RPM查询语句二选一即可:
# 直接用1分钟窗口计算增量,结果就是单分钟请求数 sum by(service) ( sum without (shard, replica, container_id) ( increase(django_http_requests_before_middlewares_total{namespace="name"}[1m15s]) ) )
这里窗口设置为1分15秒,是为了覆盖fluent-bit 15秒采集间隔带来的样本缺口,减少Prometheus线性外插带来的误差。# 用每秒速率乘以60转成每分钟值,效果和上面等价 sum by(service) ( sum without (shard, replica, container_id) ( rate(django_http_requests_before_middlewares_total{namespace="name"}[1m15s]) * 60 ) ) - 对齐面板统计粒度
- Grafana查询的步长(step)设置为1分钟,和AWS目标组默认的1分钟统计粒度对齐
- 不要用5分钟及以上的计算窗口,窗口越长,平均后的数值和单分钟统计值偏差越大
- 服务运行时长指标实现
直接取进程启动时间计算即可,PromQL如下,结果可在Grafana中转换为天/小时格式展示:max by(service) ( time() - process_start_time_seconds{namespace="name"} )
注意:不需要追求两个平台的数值100%完全相等。fluent-bit采集存在15秒以内的延迟,Prometheus和AWS的统计窗口不可能完全毫秒级对齐,再加上负载均衡层可能存在少量没打到后端的异常请求,两边数值误差稳定在3%以内就属于正常对齐状态。
内容的提问来源于stack exchange,提问作者pratik
相关产品推荐
相关产品推荐

