首次归档:2026-09-12 R2 | 难度:进阶
场景:
高并发秒杀系统,单机 QPS 峰值 3 万。架构:Nginx + Spring Boot + Redis + MySQL。
线上问题:
问题:
(未作答,进入讲解模式)
优点:暂无
不足:CPU/Redis/MySQL 三层排查是稳定性工程的核心,应能张口就来。
补充:完整讲解见下。
得分:N/A
第1步: top / htop 看 CPU 各状态(us/system/iowait)
第2步: top -Hp <pid> 定位高 CPU 线程
第3步: printf "%x\n" <tid> → jstack 搜索线程栈
第4步: Arthas profiler 或 async-profiler 生成火焰图
秒杀场景常见原因:Redis 序列化反序列化、死循环、频繁 GC、线程数过多导致上下文切换。
| 原因 | 解决方案 |
|---|---|
| 连接数配置太小 | maxTotal 按 QPS × 平均响应时间配置 |
| 连接泄漏 | 异常时确保 release,用 try-finally |
| 慢查询阻塞 | 避免大 key,检查 slow query |
| 连接超时太短 | 网络抖动导致连接被踢 |
秒杀优化:本地缓存热点 key(Caffeine)、读写分离、连接池按业务隔离。
-- 查当前事务
SELECT * FROM information_schema.INNODB_TRX;
-- 查锁等待关系(MySQL 8.0+)
SELECT * FROM performance_schema.data_lock_waits;
防雪崩方案:
UPDATE ... SET version=version+1 WHERE version=?)innodb_lock_wait_timeout=5)秒杀架构参考:
请求 → Nginx限流 → 网关令牌桶 → 应用本地缓存 → Redis Lua扣库存 → MQ异步下单 → MySQL落库
题目:秒杀10万QPS下CPU95与Redis连接耗尽(含3个子问题)
难度:high
评分:⭐⭐⭐⭐(4/5)
首先解决问题,将压力降下来,在前端做一定拦截,降低用户循环请求,然后再去网关层做行为识别将黑灰用户识别进行拦截,具体黑灰识别需要对应策略引擎,或者行为分析,简单都可以依据当前秒杀或者短期的连续访问的用户进行拦截,只放入部分;然后到达业务层开始访问 redis 的流量如果都能达到 10wqps,那么就需要使用本地缓存承接了,因为是秒杀场景,库存有限,本地缓存扣完了再去扣redis,然后订单再去访问数据库;上面是业务处理流程;然后定位 cpu 问题,redis连接池耗尽,查看下是否有慢查询出现,10wqps 都访问到一个 redis 节点么?如果是热门 key 需要做额外的划分,加分片将一个 key 拆分成多个到多个 redis 节点上去承接流量;cpu95,看线程具体是哪个引起的,用 top查看进程 id,然后 top -h查看对应的线程 id,转 16 进制后去 jstack 中查看具体是什么线程出现了问题,需要先用 jstack 导出线程情况,95%的使用率基本已经无法打开 arthas了否则用 arthas 也能直观都看到线程使用情况,定位到具体线程;然后对线程内容进行分析;redis 连接池耗尽,要么是链接池配置小了,要么是有慢查询,需要查看慢查询日志,以及查看链接分布情况,是否都是访问热key 导致都访问到一个节点,如果是,就进行热 key 拆分,给热 key 进行加分区,分片到多个节点上,分散流量;mysql 锁等待 10 秒,通过慢查询定位具体信息,查看mysql 锁统计表看具体持有者,这可以异步去记性 mysql 操作,前置在 redis 中执行库存等扣除,异步去通过 mq 在进行 mysql 操作
优点:
思路全面:先降压力→前端拦截→网关风控→业务层本地缓存- 秒杀架构:本地缓存扣库存→异步落库- CPU 排查路径:top→top -Hp→16 进制→jstack- Redis 热 key 拆分提到- MySQL 锁等待分析 + Redis 前置扣库存 + MQ 异步落库
不足:
⚠️ "95% 使用率基本无法打开 arthas"表述错误(Arthas 是低开销的)- ❌ 遗漏 top 看 iowait/system 区分用户态/系统态- ❌ 遗漏 async-profiler 火焰图(比 jstack 更直观)- ❌ 遗漏 MySQL 8.0+ performance_schema.data_lock_waits- ❌ 遗漏 innodb_lock_wait_timeout 超时控制- ❌ 遗漏乐观锁(version 字段)- ❌ 遗漏网关限流(令牌桶、漏桶)