Skip to content
第 242 / 250 章架构⏱ 12 分钟阅读

第 242 章:综合调优实战

学习目标

  • 综合应用前序调优方法
  • 性能测试方法
  • 容量规划
  • 性能回归

一、综合调优方法论

二、性能测试

2.1 工具

工具特点
JMeterGUI + 分布式
wrk轻量高并发
gatlingScala DSL
LocustPython,易扩展
k6JS,云原生

2.2 WRK 示例

bash
# 12 线程, 400 连接, 30 秒
wrk -t12 -c400 -d30s \
    -H "Authorization: Bearer xxx" \
    --script=POST.lua \
    http://localhost:8080/api/orders

2.3 JMeter 测试计划

xml
<ThreadGroup>
    <numThreads>100</numThreads>
    <rampTime>30</rampTime>
    <duration>300</duration>

    <ConstantThroughputTimer>
        <throughput>1000</throughput>
    </ConstantThroughputTimer>

    <HTTPSampler>
        <domain>api.example.com</domain>
        <path>/api/orders</path>
        <method>GET</method>
    </HTTPSampler>
</ThreadGroup>

2.4 关键指标

Latency:
  - 平均(P50)
  - 90%
  - 95%
  - 99%
  - 最大

Throughput:
  - QPS
  - TPS

Error Rate:
  - 成功率 / 失败率

Resource:
  - CPU
  - Memory
  - GC 频率
  - DB 连接

2.5 全链路压测

yaml
思想: 在生产环境,用压测流量标记
  - 染色: header X-Test-Flag = 1
  - 测试数据入影子库
  - 不污染线上

工具:
  - 阿里云 PTS
  - 京东 ForceBot
  - 美团 Leak
  - 自建方案

三、性能瓶颈案例

3.1 案例 1:订单详情接口慢

阶段优化
1加缓存(JVM + Redis),命中率 95%
2DB 索引优化(联合覆盖索引)
3异步合并查询(订单 + 商品 + 用户)
4DB 读写分离
5ES 替代 DB 搜索

3.2 案例 2:整点秒杀雪崩

yaml
问题: 整点秒杀,大量缓存同时过期,DB 挂
方案:
  - 1: 缓存预热(启动时加载)
  - 2: 过期时间随机化(60-90 秒)
  - 3: Sentinel 限流保护 DB
  - 4: DB 读写分离
  - 5: 库存本地缓存 + 校验

3.3 案例 3:全链路 GC 频繁

yaml
症状: 1 分钟内 Full GC 5 次,停顿 1 秒
原因:
  - 查询返回 100 万数据(大对象)
  - 内存不够

解决:
  - 分页查,每次 1000
  - 升堆
  - 用游标
  - 流式消费(Stream)

四、性能优化清单

4.1 应用层

yaml
✅ JVM GC 调优
✅ 线程池参数合理
✅ 对象复用(StringBuilder / ThreadLocal)
✅ 避免大事务
✅ 锁粒度细化
✅ 异步处理耗时
✅ 缓存命中率 > 90%

4.2 数据层

yaml
✅ 索引覆盖所有热点查询
✅ 慢查询定期 review
✅ SQL 避免 SELECT *
✅ 读写分离
✅ 分库分表(数据量大)
✅ Connection Pool 合理

4.3 缓存层

yaml
✅ 多级缓存
✅ 热点数据预热
✅ 解决雪崩/穿透/击穿
✅ Redis 大 key 拆分
✅ Pipeline 批量操作
✅ 内存淘汰策略

4.4 网络层

yaml
✅ HTTP/2 多路复用
✅ Keep-Alive
✅ 启用压缩
✅ 启用 HTTP 缓存头
✅ CDN 加速
✅ 合理超时

4.5 架构层

yaml
✅ MQ 削峰
✅ 异步化
✅ 限流保护
✅ 熔断容错
✅ 灰度发布
✅ 多级容灾

五、性能优化效果评估

5.1 性能指标树

5.2 优化前后对比

指标优化前优化后改善
QPS100050005x
P99800 ms200 ms-75%
CPU80%50%-38%
错误率0.5%0.01%-98%
GC 频率30/min5/min-83%

5.3 指标统计

java
// 关键指标 Micrometer
public class PerfMetrics {

    @Autowired
    private MeterRegistry registry;

    public void record(String op, long startNs, boolean success) {
        Timer timer = Timer.builder("ops.duration")
            .tag("op", op)
            .tag("status", success ? "ok" : "fail")
            .register(registry);
        timer.record(Duration.ofNanos(System.nanoTime() - startNs));
    }
}

六、性能验收

6.1 验收场景

yaml
场景:
  - 正常工作: 1 倍峰值
  - 峰值压力: 历史峰值 1.5 倍
  - 极限压力: 5 倍正常
  - 持续运行: 24 小时 8 小时负载

6.2 验收标准

项目目标
峰值 QPS>= 目标 QPS
P99 延迟< 业务要求(通常 200-500 ms)
错误率< 0.1%
CPU< 75%
内存< 80%
GC 暂停< 200 ms(单次)
持续运行< 内存泄漏

6.3 持续压测

yaml
用 Jenkins + JMeter 集成:
  - nightly 跑全链路压测
  - 数据入库报告
  - 异常告警

七、容量规划

7.1 维度

yaml
数据量:
  - 当前数据
  - 年增长率
  - 表拆分阈值

流量:
  - 当前 QPS
  - 峰值 QPS
  - 业务预期增长

计算资源:
  - CPU 核
  - 内存
  - 磁盘 IO

存储:
  - 数据库
  - 文件 / OSS
  - 备份

7.2 计算示例

业务目标:
  - DAU 100 万
  - 每用户 10 请求/天
  - 峰值占 5% 流量

QPS = 100万 × 10 / (86400) / 0.05 ≈ 232

业务通常按 3x 考虑峰值:QPS 700

单机性能(QPS): 200(普通 8 核)
冗余: 1.5 倍

应用机器数 = 700 / 200 / 0.6 ≈ 6 台

7.3 资源规划

yaml
CPU:  8 核 * 6 台 = 48 核
内存: 16G * 6 = 96 GB (堆 60% = 9.6G / JVM)
DB:  32 核 + 64G + SSD
Redis: 32G 主从
消息: 6 个分区,Kafka 3 节点

八、性能文化

8.1 性能预算

yaml
每个页面:
  - JS: < 200 KB(压缩)
  - 首屏: < 1.5 秒
  - 可交互: < 3 秒

每个接口:
  - P99: < 200ms
  - 网络往返: < 5 次

8.2 性能卡(Lighthouse)

yaml
综合分:
  - Performance
  - Accessibility
  - Best Practices
  - SEO
  - PWA

集成到 CI,得分低于 80 不通过。

8.3 性能 Deck 评审

yaml
每次大改,做:
  - 数据库变更评审
  - 缓存策略评估
  - 性能影响评估
  - 容量评估

九、典型场景的最佳实践

9.1 读多写少(商品、详情页)

yaml
✅ 多级缓存(JVM + Redis)
✅ CDN 加速静态资源
✅ 动静分离
✅ 长连接 keep-alive
✅ 接口合并(订单 + 商品列表)

9.2 写多读少(日志、埋点)

yaml
✅ Kafka 削峰
✅ 批量写入
✅ 异步落库
✅ 分区策略
✅ 压缩传输

9.3 OLAP 分析(BI、报表)

yaml
✅ ClickHouse / Doris / StarRocks
✅ 物化视图
✅ 分区 + 排序键
✅ 列式存储
✅ 异步刷新

9.4 实时(推荐、监控)

yaml
✅ Flink
✅ Redis Cluster
✅ 状态后端: RocksDB
✅ 背压机制
✅ Checkpoint 配置

十、读后感(回到原点)

yaml
1. 不要过早优化
   - 八二原则
   - 找到瓶颈再改

2. 先测后改
   - 基线对比
   - 量化收益

3. 全面思考
   - 应用层 + 数据层 + 架构层
   - 兼顾一致性与可用性

4. 持续监控
   - 优化方案要在监控下工作
   - 异常及时止损

5. 性能是工程
   - 测量、分析、修改、验证
   - 反复迭代

十一、本章小结

主题关键
方法测 + 找 + 改 + 验
场景读多 / 写多 / OLAP / 实时
验收P99 / 错误率 / GC
容量业务增长 + 冗余

动手练习

  1. 用 JMeter 跑完整场景压测,记录基线
  2. 用火焰图找 3 个最大热点,优化后再测
  3. 写一个完整的容量规划报告
  4. 持续运行 24 小时压测,观察资源泄漏

下一章:第 243 章:架构总结与面试

本站基于 VitePress 构建 · 由 Codebook 团队维护