3、性能数据采集方法:操作系统级指标、应用级指标、代码级指标

性能分析这件事,说白了就是「先看到问题,再定位问题」。

但很多人一上来就扎进代码里找瓶颈,结果翻了个底朝天,发现是磁盘 IO 满了。嗯,这种亏我吃过不少。

所以这一章,我想跟你聊聊数据采集的「三层视角」——操作系统级、应用级、代码级。每一层都有它独特的价值,缺一不可。

核心观点:性能数据采集不是一次性工作,而是一个「从外到内」的漏斗过程。先看系统资源,再看应用表现,最后钻到代码细节。

性能数据采集三层模型 操作系统级 CPU / 内存 / IO / 网络 应用级 响应时间 / 吞吐量 / 错误率 代码级 火焰图 / Trace 先看资源有没有被打满 再看服务表现是否正常 最后钻到代码里找根因 常用工具 top / vmstat / iostat APM / Prometheus / 日志 perf / async-profiler / Jaeger sar / netstat / dstat Grafana 面板 Arthas / bcc / bpftrace 💡 建议:从操作系统级开始,逐层深入,不要跳层

3.1 操作系统级指标

操作系统级指标,是性能分析的「第一道防线」。

我个人习惯,遇到性能问题,先开三个终端:一个跑 top,一个跑 iostat -x 1,一个跑 vmstat 1。先看 30 秒,心里就有数了。

3.1.1 CPU 指标

  • us(user):用户态 CPU 占用。如果持续超过 70%,说明应用在密集计算。
  • sy(system):内核态 CPU 占用。超过 30% 就要警惕,可能是系统调用太频繁。
  • wa(iowait):等待 IO 的 CPU 时间。这个值高了,别急着优化代码,先看磁盘。
  • id(idle):空闲 CPU。如果 idle 很高但性能还是差,那问题大概率不在 CPU。

我的经验:有一次线上服务响应变慢,我看 top 发现 CPU 空闲 80%,但 wa 高达 40%。一查,原来是日志写得太猛,磁盘 IO 成了瓶颈。把日志级别调低,问题立刻缓解。

3.1.2 内存指标

  • total / used / free:物理内存总量、已用、空闲。
  • buff/cache:缓存和缓冲区。Linux 会尽量用空闲内存做缓存,这很正常。
  • swap:交换分区使用量。如果 swap 持续增长,说明物理内存不够了。

注意:不要只看 free 内存。Linux 的内存管理策略是「能用尽用」,free 很小不代表内存不足。关键看 swap 和 OOM Killer 日志。

3.1.3 IO 指标

  • r/s / w/s:每秒读写请求数。
  • rkB/s / wkB/s:每秒读写数据量。
  • await:IO 请求的平均等待时间(毫秒)。超过 10ms 就要注意了。
  • %util:磁盘利用率。接近 100% 说明磁盘已经饱和。

我曾经遇到一个案例:数据库写入慢,开发同学怀疑是 SQL 问题。我一看 iostat,磁盘 %util 已经 99%,await 高达 200ms。换了一块 SSD,写入延迟直接降到 2ms。你想想看,有时候问题根本不在代码里。

3.1.4 网络指标

  • 带宽利用率:看网卡是否被打满。
  • TCP 重传率:重传率高说明网络质量差或对端处理不过来。
  • 连接数:特别是 TIME_WAIT 和 CLOSE_WAIT 状态的数量。

一句话总结:操作系统级指标告诉你「资源够不够」。如果资源没打满,问题就不在系统层。

3.2 应用级指标

操作系统级指标看完了,如果资源正常,那就要看应用本身的表现了。

应用级指标,说白了就是「你的服务到底跑得怎么样」。

3.2.1 响应时间

  • 平均响应时间:容易受极端值影响,参考价值有限。
  • P50 / P90 / P99:百分位延迟。P99 超过 1 秒,用户体验就很差了。
  • 最大响应时间:偶尔的尖刺可能是 GC 或网络抖动。

我建议:重点关注 P99 和 P999。平均响应时间 100ms 看起来很美好,但 P99 可能是 5 秒。用户感知到的,往往是那个最慢的请求。

3.2.2 吞吐量

  • QPS(每秒查询数):适用于读多写少的场景。
  • TPS(每秒事务数):适用于包含写操作的事务场景。
  • RPS(每秒请求数):更通用的指标。

吞吐量和响应时间通常是「跷跷板」关系。吞吐量上去了,响应时间往往会增加。找到那个平衡点,才是关键。

3.2.3 错误率

  • HTTP 5xx 比例:超过 1% 就要报警。
  • 超时比例:超时往往意味着资源耗尽或代码阻塞。
  • 业务错误码:比如库存不足、参数校验失败等。

避坑指南:我曾经遇到一个系统,错误率一直很低,但用户投诉不断。一查才发现,错误被吞掉了——catch 了异常但没记录日志。所以,错误率指标的前提是「错误被正确上报」。

3.3 代码级指标

操作系统和应用级指标都看完了,如果还找不到根因,那就得钻到代码里了。

代码级分析,我最常用的两个工具:火焰图和分布式 Trace。

3.3.1 火焰图

火焰图是 CPU 性能分析的「终极武器」。它把函数调用栈以火焰形状展示出来,一眼就能看出哪个函数在「烧 CPU」。

# 使用 perf 生成火焰图数据
perf record -F 99 -p PID -g -- sleep 30
perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > cpu.svg
  • X 轴:采样数量,越宽说明占用 CPU 越多。
  • Y 轴:调用栈深度,越深说明调用链越长。
  • 颜色:通常橙色代表用户态代码,蓝色代表内核态代码。

我的经验:有一次线上 CPU 飙高,用火焰图一看,发现某个 JSON 序列化函数占了 40% 的 CPU。原来是把一个大对象反复序列化了很多次。改成缓存结果后,CPU 直接降了 30%。

3.3.2 Trace(分布式追踪)

在微服务架构下,一个请求会经过多个服务。Trace 就是用来追踪这个请求的完整路径。

  • Span:一次调用的基本信息,包括开始时间、结束时间、状态。
  • Trace ID:贯穿整个请求链路的唯一标识。
  • Parent Span ID:父子关系,用来构建调用树。

常用的 Trace 工具有 Jaeger、Zipkin、SkyWalking。我个人比较喜欢 Jaeger,界面清晰,查询方便。

核心思路:Trace 能告诉你「时间花在了哪里」。如果某个 Span 的耗时特别长,那就是瓶颈所在。

3.4 三层指标的联动分析

单独看某一层指标,往往得不出结论。真正的性能分析高手,是把三层指标串起来看。

现象 操作系统级 应用级 代码级 可能原因
接口响应慢 CPU us 高 P99 延迟高 火焰图显示某函数占 CPU 高 代码逻辑效率低
接口响应慢 wa 高 P99 延迟高 Trace 显示数据库查询慢 磁盘 IO 瓶颈或 SQL 慢
接口超时 网络重传率高 错误率上升 Trace 显示下游服务超时 网络问题或下游服务故障

我常用的分析流程:

  1. 先看操作系统级指标,排除资源瓶颈。
  2. 再看应用级指标,确认问题范围(哪个接口?哪个时段?)。
  3. 最后用代码级工具,定位到具体函数或代码行。

这个流程看起来简单,但很多人会跳步。嗯,跳步往往意味着走弯路。

3.5 本章小结

性能数据采集,不是把指标堆在一起就完事了。

操作系统级指标告诉你「资源够不够」,应用级指标告诉你「服务好不好」,代码级指标告诉你「代码对不对」。

三层指标,层层递进,缺一不可。

下一章,我们会聊聊如何搭建一个可持续的性能监控体系。不过那是后话了,先把今天的内容消化掉。

一句话记住:从操作系统开始,逐层深入,不要跳层。这是性能分析最稳妥的路。

想要更多资料,联系可可