Prometheus rate函数观测值不变时返回0的解决方法咨询
解决Prometheus直方图平均响应时间显示0的问题
核心问题分析
你当前的查询是先对每个实例的rate结果求和再做除法,当目标URL在5分钟窗口内没有新请求时,rate(api_duration_milliseconds_sum[5m])会返回0(因为sum无增量),导致最终结果为0,而不是你期望的历史平均响应时间(比如刚启动时的20ms)。
方案一:结合实时速率与累计平均
通过or操作符实现双逻辑:窗口内有请求时用实时速率计算平均,无请求时回退到累计的平均响应时间,同时过滤掉无请求的URL避免NaN:
( (sum(rate(api_duration_milliseconds_sum[5m])) by (url) / sum(rate(api_duration_milliseconds_count[5m])) by (url)) or (sum(api_duration_milliseconds_sum) by (url) / sum(api_duration_milliseconds_count) by (url)) ) unless sum(api_duration_milliseconds_count) by (url) == 0
方案二:先聚合实例再计算速率
如果你想先把所有机器的指标聚合后再计算速率,写法如下:
rate(sum(api_duration_milliseconds_sum) by (url)[5m]) / rate(sum(api_duration_milliseconds_count) by (url)[5m])
这种写法先将所有实例的sum和count按URL全局聚合,再对聚合后的序列计算rate,能减少实例级无请求导致的0值,但全局无请求时仍会返回0,此时可以结合方案一的or逻辑优化。
针对初始请求场景的额外优化
- 缩短rate的时间窗口(比如用
1m代替5m),更容易捕获刚启动时的少量请求增量; - 用
irate代替rate,irate对短时间内的单点增量更敏感,适合实时性要求高的场景:
(sum(irate(api_duration_milliseconds_sum[1m])) by (url) / sum(irate(api_duration_milliseconds_count[1m])) by (url)) or (sum(api_duration_milliseconds_sum) by (url) / sum(api_duration_milliseconds_count) by (url))
内容的提问来源于stack exchange,提问作者sgch
相关产品推荐
相关产品推荐

