一、性能调优概述
性能调优,说白了就是让系统跑得更快、更稳、更省资源。我做了十几年系统优化,见过太多团队一上来就「加机器」、「扩内存」,结果钱花了不少,问题还在那。
这一章,咱们先把地基打牢。搞清楚性能调优到底是什么,目标是什么,怎么做,以及——别踩哪些坑。
1.1 什么是性能调优
性能调优不是玄学,也不是拍脑袋。它是一套系统性的方法,用来发现并消除系统中的性能瓶颈。
我习惯这样定义:在有限的资源下,让系统达到最优的响应速度、吞吐量和资源利用率。
举个例子。你写了个接口,每次请求要查 5 张表,返回 200 个字段。用户等 3 秒才看到结果。这叫「能用」,但不叫「好用」。性能调优就是要把这 3 秒压到 300 毫秒以内,同时保证服务器不崩。
核心观点:性能调优不是「优化一切」,而是找到那个最拖后腿的瓶颈,把它干掉。
1.2 性能调优的目标与原则
目标其实就三个维度,我管它叫「铁三角」:
| 维度 | 说明 | 典型指标 |
|---|---|---|
| 响应时间 | 用户发出请求到收到响应的时间 | TP50、TP99、平均延迟 |
| 吞吐量 | 单位时间内系统能处理的请求数 | QPS、TPS、RPS |
| 资源利用率 | CPU、内存、磁盘、网络的使用情况 | CPU%、内存占用、IOPS |
这三个目标经常互相打架。你想想看,想把响应时间压到极致,就得堆更多资源,吞吐量可能反而下降。所以调优的本质是做权衡。
原则我总结了四条:
- 先测量,后优化——没有数据支撑的优化都是瞎猜。我在项目中遇到过,有人凭感觉说「这里慢」,结果优化完发现瓶颈根本不在这。
- 一次只改一个变量——同时改三处,出了问题你根本不知道是哪一步导致的。
- 以用户感知为准——系统内部再快,用户觉得卡就是卡。别盯着冷门指标自嗨。
- 可量化、可复现——优化前后要有对比数据,而且场景要一致。
我的习惯:每次优化前,先记录当前系统的「性能基线」。优化完再跑一遍同样的压测脚本,对比结果。没有基线,你都不知道自己到底进步了还是退步了。
1.3 性能调优的通用方法论
做调优这么多年,我总结了一套「五步法」。不管你是调数据库、调 JVM、还是调网络,这套流程都管用。
- 定义问题——用户说「慢」,到底多慢?是偶尔慢还是持续慢?哪个接口慢?
- 建立基线——跑一遍压测,拿到当前的响应时间、吞吐量、资源使用情况。
- 定位瓶颈——用工具(比如 top、perf、arthas、慢查询日志)找到最慢的那个环节。
- 制定方案——针对瓶颈提出优化策略,评估成本和收益。
- 实施验证——改代码、调参数、换架构,然后重新压测,对比基线。
下面这张图,把整个流程串起来了:
这套流程看起来简单,但真正执行到位的人不多。我见过太多人跳过「定义问题」这一步,直接上手改代码。结果改了半天,发现用户说的「慢」其实是网络延迟,跟代码没关系。
1.4 性能调优的常见误区
下面这几个坑,我几乎每个都踩过。写出来,希望你能绕开。
误区一:过早优化
「过早优化是万恶之源」——这话是 Knuth 说的。我曾经在项目初期花了两周优化一个模块,结果后来需求变了,那模块直接被砍掉。白干。
正确做法:先让系统跑起来,用数据证明哪里是瓶颈,再动手。
误区二:凭感觉优化
「我觉得这里慢」、「我猜是数据库的问题」——这种话我听得太多了。没有压测数据、没有 profiling 报告,你所谓的「感觉」大概率是错的。
正确做法:上工具。用 Arthas 看方法耗时,用慢查询日志看 SQL,用 top 看 CPU。让数据说话。
误区三:追求完美
有些同学非要把响应时间从 50ms 优化到 10ms,投入两周时间,收益却微乎其微。而系统里可能有个接口耗时 2 秒,优化一下就能降到 200ms。
正确做法:二八原则。80% 的性能问题,往往集中在 20% 的代码上。先抓大头。
误区四:忽略硬件和网络
我记得有一次,团队花了一周优化代码,结果发现是机房交换机端口限速了。代码改得再好,也跑不过物理限制。
正确做法:排查问题时,从底层往上查。先看硬件、网络、操作系统,再看中间件,最后看代码。
误区五:优化完不验证
改完代码,上线了,然后呢?没有对比数据,你怎么知道这次优化是正收益还是负收益?
正确做法:优化前后跑同样的压测脚本,对比响应时间、吞吐量、资源利用率。数据说话。
小结
这一章我们聊了性能调优的本质、目标、方法论和常见误区。说白了,调优不是炫技,而是一套严谨的工程方法。先测量,再动手,一次只改一个变量,用数据验证结果。
记住这几点,后面的路就好走了。