服务延迟直方图只配了到 0.5 秒的桶,实际 P99 已经 3 秒,面板上 histogram_quantile 一直显示 0.5,超过 2 秒的告警从来没响过。

一开始怀疑是「标签基数爆炸导致部分指标被丢弃」,查了一圈,方向不对。

真正麻烦的地方在于,几个原因的现象几乎一样。桶的上界低于真实分布,分位数被夹在最后一个桶。另一种情况是用 sum 而不是 rate 计算,历史值一直累加。

还有一种情况,抓取间隔大于请求突发周期,峰值没被采到。

第一件事是看桶的分布情况

curl -s localhost:9090/api/v1/query --data-urlencode 'query=http_request_duration_seconds_bucket' | jq '.data.result[0].value'

补上更高的桶边界

python -c "print([0.05,0.1,0.25,0.5,1,2,5,10])"

然后用 rate 重算 P99

curl -s localhost:9090/api/v1/query --data-urlencode 'query=histogram_quantile(0.99,rate(http_request_duration_seconds_bucket[5m]))' | jq '.data.result[0].value'

压一次慢请求验证告警

python slow_client.py --delay 3 --count 50

那几天正好在做别的变更,先把时间线对齐才敢动手。

别只看报错消失,验证要多做一步。P99 显示约 3 秒且随时间波动,超过 2 秒的告警能正常触发。

分位数只能落在桶边界内,桶的最高值低于真实延迟时,面板数字再稳也是假的。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189