第十八课实战:后端性能优化实战——一个接口从 2 秒到 90ms 的全过程

目标:

不是讲概念,而是演示一次 真实的性能优化过程

如何从一个 2 秒接口,优化到 90ms,并且每一步都有依据。


场景设定

接口:

java 复制代码
GET /users?page=1&size=20

表数据量:50 万条

技术栈:Spring Boot + MySQL + Redis

初始状态(问题版本)

初始代码问题点

1)SQL 问题

java 复制代码
SELECT * FROM user;
  • 无索引
  • 全表扫描
  • 返回 50 万行

2)接口问题

  • DTO 字段 30+
  • 返回整个 List
  • 打印全部日志

3)RPC 问题

java 复制代码
for(User u : list){
    rpcService.getScore(u.getId());
}

典型 N+1 调用

初始压测结果

指标 数值
P50 300ms
P90 1200ms
P99 2100ms
CPU 35%
内存 稳定

结论:不是资源打满,是逻辑慢。

第一步:SQL 优化(最大头)

动作

1)加索引

java 复制代码
CREATE INDEX idx_user_status_time 
ON user(status, create_time);

2)分页 + 字段裁剪

java 复制代码
SELECT id,name,status 
FROM user 
WHERE status=1
ORDER BY create_time DESC
LIMIT 20;

3)Explain 对比

优化前 优化后
type=ALL type=ref
rows=500000 rows=120

SQL 优化后压测

指标 数值
P99 2100 → 420ms

第二步:接口层优化

问题点

  • 返回字段过多
  • 日志拖慢
  • 序列化重

动作

DTO 裁剪

java 复制代码
class UserDTO {
  Long id;
  String name;
}

日志采样

java 复制代码
if(random()<0.01){
  log.info("users:{}", list.size());
}

接口层优化后

指标 数值
P99 420 → 180ms

第三步:RPC 优化(N+1 问题)

原始

java 复制代码
for(User u : list){
    rpc.getScore(u.id);
}

改为批量

java 复制代码
rpc.batchGetScore(ids);

RPC 优化后

指标 数值
P99 180 → 130ms

第四步:JVM 优化

观察指标

  • Minor GC 频繁
  • 对象创建多

动作

  • 复用集合
  • 减少字符串拼接
  • 调整线程池

JVM 优化后

指标 数值
P99 130 → 90ms
GC 次数 -40%

全过程对比

阶段 P99
初始 2100ms
SQL 优化 420ms
接口优化 180ms
RPC 优化 130ms
JVM 优化 90ms

优化核心逻辑总结

java 复制代码
先 SQL
再 接口
再 RPC
最后 JVM

实战中的关键判断

现象 判断
CPU 不高却慢 逻辑慢
P99 高 极端请求问题
SQL rows 巨大 索引问题
GC 多 对象创建问题

工程经验总结

不要一上来做的事

  • 不要先加缓存
  • 不要先调 JVM 参数
  • 不要先加 MQ

应该先做的事

  • 看 P99
  • Explain SQL
  • 拆链路
  • 再优化

最终一句话

性能优化不是"调参",而是"定位 → 分层 → 验证"的工程流程。

当你能把一个 2 秒接口优化到 90ms,

你就已经具备 中高级后端工程师的实战能力 了。

相关推荐
Ai拆代码的曹操4 小时前
MySQL GROUP BY 性能优化:执行计划分析 + 索引重构实战
mysql·性能优化·重构
人间凡尔赛11 小时前
React Compiler 正式落地一年:告别手动 useMemo/useCallback 的全栈实践
前端·性能优化·react
小孔龙1 天前
VSync 与同步屏障:doFrame() 的优先调度
android·性能优化
mlidongfeng1 天前
[AI][昇腾950] Scalar 性能优化
人工智能·性能优化
乐启国际旅行社有限公司1 天前
文旅小程序性能优化:分包加载+地图视口懒加载解决景区卡顿与包超限
性能优化·小程序
梦想不只是梦与想2 天前
鸿蒙性能优化:启动速度
性能优化·harmonyos·启动速度
朱容zr3331332 天前
为什么推荐使用自增主键?使用UUID作为主键的优缺点是什么?
java·运维·数据库·后端·mysql·面试·性能优化
小孔龙2 天前
RenderNode 与 DisplayList:Android 硬件加速的绘制记录与复用
android·性能优化
宁风NF2 天前
JavaScript:内存、垃圾回收、性能优化
开发语言·前端·javascript·学习·性能优化·es6
xcLeigh3 天前
KES数据库国产软硬件全信创兼容深度适配
数据库·性能优化·kes·软硬件适配