实战篇:性能压测与调优全流程
概述
本篇把第 11 周的内容串成完整流程:写压测脚本 → 跑出基线 → 定位瓶颈 → 针对性调优(JVM/Netty/DB)→ 复测对比。以一个"千人同服对战"案例,展示从发现问题到优化的工程闭环。
一、案例与基线
1.1 压测目标
案例:千人同服对战服务器
场景:1000 玩家在线 + 并发对战
指标目标:
QPS ≥ 5000
p95 RT ≤ 50ms
成功率 ≥ 99.9%
环境:8C16G 单节点 + MySQL + Redis1.2 压测客户端
java
// 协议压测客户端(模拟玩家操作)
public class LoadRunner {
private static final int USERS = 1000;
public static void main(String[] args) throws Exception {
for (int i = 0; i < USERS; i++) {
new BotPlayer(i).start(); // 每个 Bot 登录 + 周期操作
}
// 每 10 秒输出一次统计
StatsCollector.startReport();
}
}java
// Bot 玩家:连接 → 登录 → 匹配 → 对战操作
public class BotPlayer {
private final Channel channel;
void start() {
// 连接服务器(Netty)
// 登录(模拟协议)
sendLogin();
// 周期操作(匹配/出牌,模拟真实行为)
channel.eventLoop().scheduleAtFixedRate(
this::randomOperation, 0, 3, TimeUnit.SECONDS);
}
}1.3 基线结果
基线(未优化):
QPS: 2800 # 未达标(目标 5000)
p50: 8ms # 中位尚可
p95: 85ms # 超标(目标 50ms)
p99: 260ms # 长尾严重
成功率: 99.6% # 有超时失败
结论:p95/p99 超标 + QPS 不足 → 需要定位瓶颈二、瓶颈定位
2.1 资源与线程分析
定位步骤:
1. 监控面板:CPU 高(75%),内存平稳
2. Arthas thread -n 3:多个业务线程 BLOCKED
3. 火焰图:热点在 Redis 同步调用 + 序列化
结论:
CPU 热点:高频 Redis 读写(同步阻塞)
锁竞争:房间操作锁等待
GC:p99 长尾与 GC 停顿相关// Arthas 定位(关键证据)
$ thread -n 3
"biz-pool-5" Id=31 BLOCKED
at redis.clients.jedis.Jedis.get(...) // 同步 Redis
"biz-pool-8" Id=34 BLOCKED
at com.game.logic.Room.tick(...) // 房间锁2.2 问题归类
三类问题:
Redis 同步调用阻塞(IO 等待)→ 异步化/批量
房间锁竞争 → 分区串行/细锁
GC 停顿影响 p99 → JVM 调优
优先级:
先解决阻塞(收益最大)
再优化锁(并发提升)
最后 JVM 参数(长尾改善)三、调优实施
3.1 Netty 与业务线程
优化一:Redis 异步化 + 批量
高频读(在线状态)→ Pipeline/MGET 批量
高频写(排行榜)→ MQ 异步消费(见消息队列章节)
同步阻塞移出业务线程(缓存 + 批量)优化二:房间锁 → 分区串行
房间操作按 roomId 分配到固定线程(见并发章节)
消除跨房间锁竞争
房间内部单线程 → 无锁3.2 JVM 调优
优化三:JVM 参数
G1 MaxGCPauseMillis 80(默认可能更高)
堆固定(避免伸缩抖动)
观察 GC 后微调新生代比例
// 调优后参数
-Xms8g -Xmx8g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=803.3 DB 优化
优化四:数据库
慢查询 → 加索引(排行榜查询字段)
批量写入 → 批量 insert
热点数据 → Redis 缓存兜底(减少 DB 读)
// 慢查询示例(此前 EXPLAIN 全表扫描)
ALTER TABLE player_currency ADD INDEX idx_cur_player(player_id);四、复测对比
4.1 优化后结果
优化后(同场景):
QPS: 6200 # 达标(目标 5000)
p50: 4ms # 改善
p95: 22ms # 达标(目标 50ms)
p99: 68ms # 长尾明显改善
成功率: 99.97% # 达标
对比:
指标 优化前 优化后 提升
QPS 2800 6200 +121%
p95 85ms 22ms 74%↓
p99 260ms 68ms 74%↓4.2 验证与回归
验证项:
功能回归(压测期间对局正常结算)
稳定性(持续压测 2 小时无泄漏)
容量拐点(继续加压找新上限)
弱网模拟(延迟/丢包下表现)
结论:
本轮优化达标 → 可上线
记录优化清单供后续参考五、关键要点回顾
完整流程:
1. 明确目标(QPS/RT/成功率)
2. 写压测脚本(协议级模拟)
3. 跑基线 → 找差距
4. 定位瓶颈(监控 + Arthas + JFR)
5. 分类调优(阻塞/锁/GC/DB)
6. 复测对比(量化提升)
7. 回归验证(功能 + 稳定性)
工具链:
压测:自研 Netty 客户端
定位:Arthas + JFR + 监控
调优:Netty/JVM/DB(对应各章节)
验证:指标对比 + 稳定性
常见教训:
不量化对比的"优化"无意义
只看 p50 忽视长尾
单点优化不系统性验证
压测场景不贴近真实