第一章:压测崩盘现场实录 —— 一场价值百万的故障诊断
1.1 大促压测事故还原
时间:凌晨2:15
监控指标:
- QPS从8万骤降至1200
- Full GC频率飙升至30次/分钟,单次停顿4.2秒
- 线程池队列堆积超过50万请求
故障定位三板斧:
- 即时线程Dump分析(基于Arthas)
bashCopy Code
# 快速捕获线程状态
thread --all > thread_dump.log
# 统计阻塞线程
cat thread_dump.log | grep "BLOCKED" | awk '{print $2}' | sort | uniq -c
发现OrderService的库存校验方法有128个线程卡在synchronized锁竞争。
- 内存泄漏追踪(MAT工具实战)
- 发现17GB的JSON解析缓存未释放,原因为第三方SDK未正确关闭流对象。
- 数据库慢查询溯源
sqlCopy Code
# 实时捕获执行计划
EXPLAIN ANALYZE
SELECT * FROM order_items
WHERE sku_id IN (...5000个参数...);
问题暴露:全表扫描 + 临时表排序,单查询耗时8.3秒。
第二章:JVM调优黑皮书 —— 参数背后的物理战争
2.1 G1GC配置的微观调控
bashCopy Code
# 百万QPS场景终极配置(64核/256G物理机)
-XX:+UseG1GC
-XX:G1HeapRegionSize=16m # 匹配订单DTO对象平均大小12.8MB
-XX:MaxGCPauseMillis=150 # 平衡吞吐量与延迟
-XX:G1NewSizePercent=45 # 根据Eden区对象存活时间调整
-XX:G1MaxNewSizePercent=70
-XX:InitiatingHeapOccupancyPercent=40 # 提前触发混合GC
-XX:G1MixedGCLiveThresholdPercent=88 # 严格筛选回收区域
-XX:G1HeapWastePercent=5 # 控制碎片率
-XX:G1OldCSetRegionThresholdPercent=15 # 老年代回收比例
2.2 ZGC实验性调优(JDK17实战)
bashCopy Code
# 超低延迟场景配置(适用于金融交易系统)
-XX:+UseZGC
-XX:ZAllocationSpikeTolerance=5.0 # 容忍突发内存分配
-XX:ZCollectionInterval=300 # 主动GC周期(秒)
-XX:ZProactive # 启用预测性GC
-XX:ZUncommitDelay=300 # 内存归还延迟
第三章:线程池军火库升级 —— 从基础到自适应
3.1 动态线程池核心算法
javaCopy Code
// 基于QPS的自动扩缩容算法(核心代码片段)
public void adjustPool(ThreadPoolExecutor executor) {
double loadFactor = executor.getActiveCount() / (double)executor.getMaximumPoolSize();
long avgWaitTime = getQueueAvgWaitTime(); // 自定义监控方法
if (loadFactor > 0.8 && avgWaitTime > 1000) {
int newMax = Math.min(executor.getMaximumPoolSize() * 2, absoluteMax);
executor.setMaximumPoolSize(newMax);
log.warn("线程池扩容至 {}", newMax);
} else if (loadFactor < 0.3 && avgWaitTime < 50) {
int newMax = Math.max(executor.getCorePoolSize(), (int)(executor.getMaximumPoolSize() * 0.7));
executor.setMaximumPoolSize(newMax);
log.info("线程池缩容至 {}", newMax);
}
}
3.2 线程上下文优化实战
问题:每秒超过50万次的MDC日志参数传递导致性能损耗。
解决方案:
javaCopy Code
// 自定义线程池包装器(减少ThreadLocal复制)
public class MdcThreadPool extends ThreadPoolTaskExecutor {
@Override
public void execute(Runnable task) {
Map<String, String> context = MDC.getCopyOfContextMap();
super.execute(() -> {
if (context != null) MDC.setContextMap(context);
try {
task.run();
} finally {
MDC.clear();
}
});
}
}
效果:线程切换耗时降低62%。
第四章:数据库核弹防御 —— 从索引到分布式事务的终极优化
4.1 索引跳跃扫描黑科技
慢SQL原罪:
sqlCopy Code
SELECT * FROM orders
WHERE shop_id = 123
AND create_date > '2023-01-01'
ORDER BY customer_id LIMIT 100000,10;
优化方案:
sqlCopy Code
ALTER TABLE orders ADD INDEX idx_shop_customer_date
(shop_id, customer_id, create_date);
# 改写查询语句
SELECT * FROM orders
WHERE shop_id = 123
AND customer_id >= (SELECT customer_id FROM orders WHERE shop_id=123 ORDER BY customer_id LIMIT 100000,1)
ORDER BY customer_id
LIMIT 10;
效果:执行时间从12秒→27毫秒。
4.2 分布式事务优化矩阵
|
方案 |
TPS上限 |
适用场景 |
风险点 |
|
XA协议 |
1500 |
强一致性要求 |
死锁检测复杂 |
|
TCC补偿 |
8500 |
长事务业务 |
补偿逻辑难实现 |
|
本地消息表 |
12000 |
最终一致性 |
消息积压风险 |
|
SAGA模式 |
20000 |
复杂业务流程 |
调试难度高 |
第五章:缓存宇宙的维度战争 —— 从本地缓存到多级联邦
5.1 Caffeine配置秘籍
javaCopy Code
// 电商商品详情缓存配置
LoadingCache<String, ProductDetail> cache = Caffeine.newBuilder()
.maximumSize(20_000) // 基于条目数限制
.weigher((String key, ProductDetail pd) -> pd.getImages().size() + 2) // 自定义权重
.expireAfterAccess(30, TimeUnit.MINUTES)
.refreshAfterWrite(5, TimeUnit.MINUTES) // 异步刷新
.recordStats()
.build(key -> {
ProductDetail pd = redis.get(key);
if (pd == null) pd = db.load(key);
return pd;
});
5.2 缓存一致性时空穿越解决方案
javaCopy Code
// 基于版本号的多级缓存更新策略
public void updateProduct(Product product) {
// 1. 更新数据库
db.update(product);
// 2. 生成新版本号
long newVersion = System.currentTimeMillis();
// 3. 两级缓存更新顺序
redis.set(product.getId(), product, newVersion); // Redis带版本号
localCache.invalidate(product.getId()); // 本地缓存立即失效
// 4. 异步广播通知其他节点
mq.sendVersionUpdate(product.getId(), newVersion);
}
第六章:百万QPS的终极验证 —— 混沌工程全纪实
6.1 真实故障模拟清单
|
故障类型 |
注入方式 |
防御验证指标 |
|
网络分区 |
iptables -A INPUT -p tcp --dport 6379 -j DROP |
集群自动切换耗时 < 3s |
|
CPU爆满 |
stress -c 32 --timeout 300 |
线程池拒绝请求数 < 100/秒 |
|
磁盘IO夯死 |
dd if=/dev/zero of=/test.img bs=512M count=4 |
日志写入延迟 < 500ms |
6.2 全链路压测数据看板
压测指标:
textCopy Code
QPS:1,234,567
TPS:987,654
平均RT:23ms
P99延迟:178ms
错误率:0.0003%
资源消耗:
|
节点类型 |
CPU使用率 |
内存占用 |
网络吞吐 |
|
应用服务器 |
68% |
72G/128G |
1.2Gbps |
|
Redis集群 |
41% |
48G/64G |
890Mbps |
|
数据库 |
63% |
156G/256G |
680Mbps |
第七章:性能革命的23条军规(血泪总结)
- JVM参数:-XX:+AlwaysPreTouch 启动时预热内存页(避免运行时缺页中断)
- 线程池:核心线程数 ≠ 最大线程数,动态扩容间隔应 ≥ 30秒
- SQL优化:联合索引字段顺序遵守 AER原则(等值查询在前,范围在后,排序最后)
- 缓存策略:热点Key检测算法需满足 T时间内访问次数 > 3σ(标准差)
- 混沌工程:每月至少执行一次随机杀节点演练
附录:工具链全家福
- 诊断工具:
- Arthas:线上线程/内存实时分析
- async-profiler:无侵入式性能剖析
- 压测工具:
- Venom:全链路染色压测系统
- Tank:阿里开源生产流量回放工具
1035

被折叠的 条评论
为什么被折叠?



