2、监控体系设计原则:从用户视角和系统视角定义监控指标,理解黄金信号

监控体系怎么搭?很多人一上来就堆指标,CPU、内存、磁盘……全给整上。结果呢?告警铺天盖地,真正出问题的时候反而被淹没了。

我个人习惯,设计监控体系之前,先问自己两个问题:

  • 用户觉得慢了吗? —— 这是用户视角
  • 系统哪里扛不住了? —— 这是系统视角

说白了,监控不是为了看数据,是为了回答「服务还正常吗?」这个问题。今天我们就聊聊怎么从这两个视角出发,再结合 Google 提出的黄金信号,把监控体系搭得明明白白。

2.1 用户视角 vs 系统视角

先讲个我踩过的坑。有一次线上告警说磁盘 IO 满了,我盯着 Grafana 看了半天,CPU 正常、内存正常、延迟也正常。正纳闷呢,用户投诉就来了——搜索页面打不开了。

为什么会这样?因为磁盘 IO 满了之后,缓存写不进去,新数据进不来,搜索结果自然就空了。但我的监控只盯着「系统资源」,没盯着「用户能不能搜到结果」。

这就是两个视角的区别:

视角 关注点 典型指标 谁最在意
用户视角 服务是否可用、响应是否及时 延迟、错误率、可用性 用户、产品经理
系统视角 资源是否充足、组件是否健康 CPU、内存、磁盘、连接数 运维、开发

我建议,用户视角的指标应该放在告警的第一优先级。系统视角的指标,更多是用来做根因分析的。举个例子:

  • 用户视角告警:搜索 P99 延迟超过 2 秒 → 立刻响应
  • 系统视角告警:ES 集群 GC 时间超过 10% → 排查原因,不一定立刻拉人

你想想看,如果用户没感觉到慢,系统指标再难看,其实也不用太紧张。反过来,用户已经骂街了,你还在看 CPU 温度,那就本末倒置了。

2.2 黄金信号:延迟、流量、错误、饱和度

Google 的 SRE 团队总结过四个黄金信号,我用了这么多年,确实管用。它们覆盖了用户视角和系统视角的核心维度。

2.2.1 延迟(Latency)

延迟就是「用户等多久」。但这里有个坑——平均延迟是骗人的

我记得有一次,搜索接口的平均延迟只有 200ms,看起来挺正常。结果一查 P99,好家伙,5 秒!原来 99% 的请求都很快,但剩下 1% 的请求慢到离谱。而这 1% 的用户,恰恰是最活跃的那批。

关键指标:

  • P50(中位数):代表大部分用户的体验
  • P95 / P99:代表最差情况下的体验
  • P999:核心服务建议关注,比如支付、搜索

我个人习惯,告警阈值设在 P99 上。P50 波动大一点没关系,P99 一旦超过阈值,说明有用户真的在受苦了。

2.2.2 流量(Traffic)

流量就是「系统承受了多少压力」。对于搜索引擎来说,流量指标包括:

  • QPS(每秒查询数)
  • 吞吐量(每秒处理的数据量)
  • 并发连接数

流量本身不是问题,问题是流量突增时系统能不能扛住。我曾经遇到过双十一流量翻了 5 倍,监控上 QPS 曲线直接拉满,但延迟居然没怎么变——因为提前做了限流和扩容。这就是流量监控的价值:让你知道什么时候该扩容了

小技巧:流量监控最好配合「同比」和「环比」来看。比如今天上午 10 点的 QPS 比昨天同一时间高了 30%,那就要警惕是不是有异常流量进来了。

2.2.3 错误(Errors)

错误分两种:

  • 显式错误:HTTP 500、超时、返回码异常
  • 隐式错误:返回了 200,但内容是空的,或者数据是错的

显式错误好抓,隐式错误才是大坑。我印象很深的一次,搜索接口返回了 200,但结果页是空白的——因为后端索引挂了,但网关层没报错。用户刷新了十几次,全是空白,气得直接投诉。

所以,我建议错误监控要加上「业务层面的校验」。比如:

# 伪代码示例:检查搜索结果是否为空
def check_search_response(response):
    if response.status_code == 200:
        if response.json().get('total') == 0:
            alert("搜索结果为空,可能索引异常")
    else:
        alert(f"HTTP错误: {response.status_code}")

注意:错误率不能只看绝对值。比如平时错误率 0.1%,突然涨到 1%,虽然绝对值不高,但已经是 10 倍增长了。建议用「错误率突增倍数」来设置告警。

2.2.4 饱和度(Saturation)

饱和度就是「系统还有多少余量」。说白了,就是看系统快不行了没有。

常见的饱和度指标:

  • CPU 使用率(超过 80% 就要注意)
  • 内存使用率(接近上限时会有 OOM 风险)
  • 磁盘 IO 等待时间(超过 50ms 说明磁盘扛不住了)
  • 连接池使用率(连接数快满了,新请求就得排队)

这里有个经验:饱和度告警要留提前量。比如磁盘用到 80% 就告警,别等到 95% 再告——那时候可能已经来不及扩容了。

我曾经吃过这个亏。有一次磁盘使用率到了 90%,我觉得还能撑一撑。结果半夜流量一上来,日志疯狂写入,磁盘直接满了,服务挂了半小时。从那以后,我的磁盘告警阈值就改成了 75%。

2.3 如何组合使用黄金信号

四个信号不是孤立的,它们之间有关系。我一般这样组合:

  1. 先看延迟和错误:用户是不是在遭罪?
  2. 再看流量:是不是流量突增导致的?
  3. 最后看饱和度:系统资源是不是到瓶颈了?

举个例子:

  • 延迟飙升 + 错误率上升 → 大概率服务挂了,立刻响应
  • 延迟飙升 + 流量正常 + CPU 饱和 → 可能是代码性能问题,排查慢查询
  • 延迟正常 + 错误率正常 + 磁盘饱和 → 提前扩容,别等出问题

总结一下:

监控体系设计,核心就两句话:从用户视角定义「好不好」,从系统视角定义「为什么不好」。黄金信号帮你把这两个视角串起来,不漏掉关键信息,也不被噪音淹没。

嗯,这一章就聊到这儿。下一章我们讲讲具体的监控工具选型,Prometheus 和 Grafana 怎么搭,以及告警规则怎么写才不扰民。到时候我会分享一些我踩过的坑,保证实用。