资讯动态

系统监控与可观测性实战:从指标采集到告警设计的核心逻辑

发布时间:2026/10/20 18:01:23 来源:尧图企业网站定制
1. 从“monitor”这个词说起它到底指什么“monitor”这个词在技术圈里出现的频率极高但每次出现时含义可能完全不同。有人说的 monitor 是操作系统里的管程Monitor有人说的 monitor 是监控系统Monitoring System还有人说的 monitor 是显示器硬件。这篇学习笔记要聊的是我在实际项目中反复接触到的那个 monitor——系统监控与可观测性。为什么突然想写这个因为我在带新人的过程中发现一个很普遍的现象很多人对 monitor 的理解停留在“装个 Prometheus配个 Grafana 面板”这个层面。你问他为什么要监控、监控什么、告警阈值怎么定他答不上来。这就好比一个人买了全套工具箱但你问他螺丝刀是干嘛用的他说“拧螺丝的”——没错但拧哪里的螺丝、为什么要拧、拧多紧这些才是关键。monitor 的本质是什么我的理解是用可量化的数据回答“系统现在是否正常”这个问题并且在异常发生之前或之初就发出信号。注意这里有两个关键词——“可量化”和“在异常发生之前或之初”。不可量化的感觉比如“我觉得系统有点慢”不叫 monitor事后诸葛亮比如用户投诉了才发现挂了也不叫 monitor那叫事故响应。这篇文章适合谁看如果你刚开始接触系统监控或者已经在用一些监控工具但总觉得“哪里不对”又或者你正在搭建自己的监控体系但不知道从何下手那这篇笔记应该能帮到你。我会从监控的核心模型讲起然后拆解指标采集、数据存储、告警规则、可视化这几个环节最后分享一些我在实际项目中踩过的坑和总结的经验。2. 监控体系的四个核心问题先想清楚再动手2.1 监控到底在监控什么很多人一上来就问“用什么工具”我觉得这个顺序反了。应该先问“我要监控什么”。从我的经验来看监控对象可以分成四个层次基础设施层CPU、内存、磁盘、网络。这是最底层的也是最好采集的。但要注意这些指标“正常”不代表系统“正常”。我见过 CPU 利用率只有 20% 但服务响应时间飙升的情况原因是线程池被慢查询占满了。中间件层数据库连接数、消息队列堆积量、缓存命中率、连接池状态。这一层往往是问题的重灾区。举个例子数据库连接池被打满应用层表现是请求超时但如果你只监控应用层的响应时间你只能知道“出问题了”不知道“为什么出问题”。应用层QPS、响应时间P50/P95/P99、错误率、饱和度。这是最贴近业务的监控层。这里有个经验平均值会骗人。平均响应时间 100ms 看起来很好但如果 P99 是 5 秒意味着每 100 个用户就有 1 个在骂娘。业务层订单量、支付成功率、活跃用户数、关键业务转化率。这一层是给老板和产品经理看的但对技术人员同样重要——因为技术问题最终会反映在业务指标上。2.2 四种监控信号类型业界有个比较成熟的分类框架把监控信号分成四类Metrics指标、Logs日志、Traces链路追踪、Profiles性能剖析。我简单说一下我的理解Metrics 是数值型的时间序列数据比如“过去 5 分钟的平均响应时间”。它的优势是存储成本低、查询快、适合做告警。缺点是粒度粗丢失了很多细节。Logs 是离散的事件记录比如“2024-01-15 10:23:45 用户 12345 请求 /api/order 失败错误码 500”。它的优势是信息量大、适合排查具体问题。缺点是存储成本高、查询慢。Traces 是请求级别的调用链路能告诉你一个请求经过了哪些服务、每个服务耗时多少。它的优势是能定位跨服务的性能瓶颈。缺点是需要侵入式埋点对代码有改造要求。Profiles 是代码级别的性能数据比如“哪个函数占用了最多 CPU”。它的优势是能定位到代码行级别。缺点是对运行时性能有影响通常只在排查特定问题时开启。我的建议是Metrics 做日常监控和告警Logs 做问题排查Traces 做性能优化Profiles 做深度分析。不要试图用一种信号解决所有问题。2.3 告警阈值的设定逻辑这是我最想强调的一点。很多团队的告警阈值是拍脑袋定的——“CPU 超过 80% 就告警”。但你想过没有为什么是 80%70% 行不行90% 行不行我的经验是阈值应该基于历史数据和业务影响来定而不是基于“感觉”。具体做法是第一步收集至少两周的历史数据看看正常情况下的波动范围。如果 CPU 平时就在 60%-75% 之间波动那 80% 的阈值可能太紧了会频繁误报。第二步分析历史故障看看故障发生前哪些指标出现了异常。比如某次故障前数据库连接数从 50 飙升到 200那连接数的阈值就应该设在 150 左右。第三步区分告警级别。P0 告警电话短信只留给真正影响用户的问题P1 告警IM 消息留给需要关注但不紧急的问题P2 告警邮件留给趋势性变化。我踩过的一个坑早期把所有告警都设成 P0结果半夜被 CPU 告警吵醒爬起来一看是定时任务在跑。后来我把告警分了级P0 只留给“用户可感知的故障”睡眠质量直线上升。2.4 监控数据的保留策略监控数据不是存得越久越好。原始精度数据比如 10 秒一个点存 15 天就够了再久的数据可以降精度存储比如 1 分钟一个点存 3 个月1 小时一个点存 1 年。这样既能满足排查需求又能控制存储成本。我见过一个团队所有监控数据都按 10 秒精度存了两年结果存储费用比服务器本身还贵。后来做了分级存储成本降了 70%。3. 指标采集的实操细节从埋点到入库3.1 采集方式的选择推还是拉监控数据的采集有两种模式推Push和拉Pull。推模式是客户端主动把数据发送到服务端。优点是实时性好、适合短生命周期任务比如定时任务跑完就没了拉模式可能来不及拉取。缺点是客户端需要知道服务端地址、网络问题可能导致数据丢失。拉模式是服务端定期去客户端拉取数据。优点是服务端控制节奏、容易发现客户端宕机拉不到就是挂了。缺点是对于短生命周期任务不友好、需要维护目标列表。我的建议是长期运行的服务用拉模式短生命周期任务用推模式。很多现代监控系统两种都支持可以根据场景灵活选择。3.2 指标命名规范这个看起来是小事但实际影响很大。我见过指标命名混乱导致的后果两个人分别采集了同一个指标但一个叫cpu_usage一个叫cpu_usage_percent结果做聚合分析时对不上。我的命名规范建议是使用小写字母和下划线http_request_duration_seconds包含单位_seconds、_bytes、_total使用标签区分维度而不是把维度写进指标名用http_requests{methodGET, status200}而不是http_get_200_count计数器用_total后缀表示只增不减3.3 埋点位置的选择应用层监控的埋点位置很关键。我的经验是入口处埋点在请求进入应用的第一层埋点记录请求总量、响应时间、状态码。这能反映用户感知到的服务质量。关键依赖处埋点在调用数据库、缓存、外部服务的地方埋点记录调用耗时和成功率。这能帮你快速定位是自身问题还是依赖问题。业务逻辑关键节点埋点在核心业务流程的关键步骤埋点比如“订单创建成功”“支付回调处理完成”。这能把技术指标和业务指标关联起来。一个实用技巧埋点时记录一个trace_id这样当 Metrics 显示异常时你可以用trace_id去 Logs 里查具体发生了什么。Metrics 和 Logs 的联动能大幅缩短排查时间。3.4 采集频率的权衡采集频率越高数据越精细但存储和计算成本也越高。我的经验值是基础设施指标CPU、内存15-30 秒一次应用指标QPS、响应时间10-15 秒一次业务指标订单量1 分钟一次日志实时采集但可以做采样比如只采集 10% 的 DEBUG 日志对于特别重要的指标可以适当提高频率。但要注意采集频率过高本身也会消耗资源形成“观测者效应”。4. 数据存储与查询时序数据库的选型思路4.1 为什么需要专门的时序数据库有人可能会问我用 MySQL 存监控数据不行吗短期可以长期不行。原因有三第一写入量太大。假设 100 个指标每个指标 10 秒采集一次一天就是 864000 个数据点。MySQL 在这种写入压力下性能会急剧下降。第二查询模式不同。监控查询通常是“过去 1 小时的平均值”“过去 7 天的 P99”这种聚合查询在关系型数据库里效率很低。第三数据过期策略不同。监控数据需要自动过期删除关系型数据库做这个很别扭。时序数据库TSDB就是为这种场景设计的。它在写入性能、聚合查询、数据过期方面都有专门优化。4.2 选型时关注的几个维度市面上的时序数据库不少选型时我主要看这几个维度写入性能每秒能写入多少数据点。这个指标决定了你能采集多细的粒度。查询性能聚合查询的响应时间。这个指标决定了你的 Grafana 面板能不能秒开。存储效率压缩比如何。好的时序数据库能把数据压缩到原始大小的 1/10 甚至更低。运维复杂度单机还是集群、是否需要额外依赖。对于小团队运维复杂度往往比性能更重要。生态兼容性是否支持 PromQL 或类似的查询语言、是否有现成的 Grafana 数据源插件。4.3 数据降精度与过期策略前面提到过监控数据应该分级存储。具体怎么做呢假设原始数据是 10 秒一个点保留 15 天。然后通过降精度任务把 10 秒数据聚合成 1 分钟数据取平均值、最大值、最小值保留 90 天。再聚合成 1 小时数据保留 1 年。这样做的逻辑是越久远的数据你越不需要看那么细的粒度。你排查昨天的问题可能需要 10 秒精度但排查三个月前的问题1 小时精度就够了。注意降精度时不仅要保留平均值还要保留最大值和最小值。因为平均值会掩盖尖峰而尖峰往往是问题的信号。5. 告警规则的设计与优化从“狼来了”到“精准打击”5.1 告警规则的基本结构一条告警规则通常包含这几个部分查询表达式从时序数据库里查出需要判断的指标持续时间条件持续多久才触发告警阈值触发告警的临界值告警级别P0/P1/P2通知渠道电话/短信/IM/邮件举个例子avg(http_request_duration_seconds{jobapi}) 0.5 for 5m。意思是 API 服务的平均响应时间超过 500ms 且持续 5 分钟就触发告警。5.2 减少误报的几种手段误报是监控系统最大的敌人。频繁的误报会让团队对告警麻木真正的问题反而被忽略。我总结了几种减少误报的手段使用持续时间不要一超过阈值就告警而是持续一段时间再告警。这能过滤掉毛刺。使用多条件组合比如“CPU 高 且 响应时间高”才告警单独 CPU 高可能是正常波动。使用动态阈值基于历史数据自动计算阈值而不是固定值。比如“超过过去 7 天同一时段的 3 倍标准差”。使用告警分组把相关的告警合并成一条通知避免告警风暴。使用静默期在发布、维护等已知会触发告警的时间段提前静默相关告警。5.3 告警分级与通知策略告警分级不是拍脑袋定的而是基于业务影响和紧急程度。我的分级标准是级别定义通知方式响应要求P0用户可感知的故障核心功能不可用电话短信IM立即响应P1非核心功能异常或核心功能性能下降IM短信30分钟内响应P2趋势性异常暂不影响用户IM当天处理P3提示性信息无需立即处理邮件按需处理一个经验P0 告警一定要少。如果 P0 告警每天超过 3 条说明要么系统太不稳定要么分级标准有问题。5.4 告警内容的编写规范告警内容要能让接收者不看监控面板就能判断问题严重程度和大致方向。我建议包含以下信息告警名称简洁明了比如“API 响应时间过高”当前值比如“当前 P99 响应时间 2.3s”阈值比如“阈值 1s”持续时间比如“已持续 8 分钟”影响范围比如“影响 /api/order 接口”相关链接监控面板链接、日志查询链接、Runbook 链接6. 可视化面板的设计让数据说话6.1 面板布局的基本原则Grafana 面板不是越花哨越好。我的布局原则是从上到下从粗到细最上面放核心业务指标一眼看全局中间放应用指标定位问题方向下面放基础设施指标深入排查细节。从左到右从因到果左边放原因类指标CPU、连接数右边放结果类指标响应时间、错误率。这样排查时视线从左到右移动符合因果逻辑。重要指标放大核心指标用大面板辅助指标用小面板。不要让次要信息占据主要位置。6.2 图表类型的选择不同数据适合不同的图表类型时间序列折线图适合看趋势当前状态单值图或仪表盘适合看“现在怎么样”分布情况热力图适合看 P50/P95/P99 的分布对比分析柱状图适合看不同维度的对比占比分析饼图适合看各部分的占比但饼图不宜超过 5 个分类6.3 变量与模板化Grafana 的变量功能非常实用。你可以定义$instance、$job、$interval等变量让一个面板适配多个实例或时间范围。这样不用为每个服务单独建面板维护成本大幅降低。一个实用技巧把常用的查询时间段做成变量比如$range这样可以在面板上快速切换“最近 1 小时”“最近 24 小时”“最近 7 天”。7. 实际项目中踩过的坑与经验总结7.1 监控系统本身的监控这是个容易被忽略的问题监控系统自己挂了怎么办我遇到过 Prometheus 因为磁盘写满而停止采集的情况结果那段时间的监控数据全部丢失。解决方案是监控系统本身也要被监控。具体来说监控采集组件的存活状态进程是否在、端口是否通监控存储组件的磁盘使用率、写入延迟监控告警通道的可用性发一条测试告警看是否能收到设置“心跳告警”如果监控系统超过一定时间没有上报数据就触发告警7.2 监控数据与日志的关联前面提到过trace_id的作用。实际项目中我建议在应用层统一注入trace_id并在日志和监控指标中都带上这个 ID。这样当监控告警时你可以直接点击链接跳到日志系统用trace_id查出完整的请求链路。7.3 监控覆盖率的评估怎么知道监控覆盖得够不够我的方法是做“故障演练”故意制造一些故障比如杀掉一个进程、模拟网络延迟看监控系统能不能发现、多久能发现、告警内容是否准确。如果某个故障监控系统发现不了说明存在监控盲区需要补充采集或告警规则。7.4 团队协作与 Runbook监控告警不是终点而是起点。收到告警后应该怎么做这就需要 Runbook操作手册。Runbook 应该包含告警的含义和可能的原因排查步骤先看什么、再看什么常见的修复方法升级路径搞不定找谁我的经验是Runbook 不要写太长一页纸就够了。太长的 Runbook 没人看。关键是要把“第一步做什么”写清楚。7.5 监控体系的演进节奏不要试图一次性搭建完美的监控体系。我的建议是分阶段演进第一阶段核心指标采集 基础告警。先保证“系统挂了能知道”。第二阶段完善应用层监控 告警分级。做到“知道哪里挂了”。第三阶段引入链路追踪 日志关联。做到“知道为什么挂了”。第四阶段业务监控 智能告警。做到“在用户感知之前发现问题”。每个阶段之间留出时间让团队适应不要跳步。8. 一些值得关注的细节8.1 时间同步问题监控数据的时间戳依赖各服务器的时间同步。如果服务器时间不同步会导致数据错乱、告警误判。确保所有服务器都配置了 NTP 时间同步并且定期检查同步状态。8.2 监控数据的采样与聚合对于高基数指标比如每个用户 ID 一个标签直接采集会导致存储爆炸。这时候需要做采样或预聚合。比如只采集 P99 而不是所有原始值或者按用户分组而不是按单个用户。8.3 告警的“疲劳管理”如果团队对告警产生疲劳再好的监控体系也白搭。定期回顾告警记录分析哪些告警是无效的、哪些可以合并、哪些阈值需要调整。我建议每个月做一次“告警回顾”持续优化。8.4 监控与成本监控不是免费的。存储、计算、网络都有成本。在设计监控体系时要平衡“监控粒度”和“成本”。我的原则是核心指标高精度、次要指标低精度、非必要指标不采集。9. 写在最后监控这件事说到底是“用数据驱动运维决策”。工具会变、技术会变但核心逻辑不变采集数据、存储数据、分析数据、基于数据做决策。我在实际项目中的体会是好的监控体系不是建出来的而是迭代出来的。一开始不用追求大而全先把核心指标监控起来然后根据实际遇到的问题逐步完善。每次故障都是一次优化监控的机会——故障发生后问自己“如果监控更完善能不能更早发现”然后把答案落实到监控体系中。最后分享一个小技巧在每次故障复盘时除了写“故障原因”和“修复措施”再加一项“监控改进”。这样监控体系会随着每一次故障变得越来越完善而不是原地踏步。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑