如果活动很火爆,有100万QPS的访问量,只持续一分钟,或者5分钟的话,只有一个节点的话根本扛不住,怎么处理?
面对 100 万 QPS 的短暂高并发,单节点无法承受,需通过分布式架构、流量控制和缓存优化处理: 1. 分布式部署:多节点分担流量(如 100 台机器,每台 1 万 QPS)。 2. 负载均衡:Nginx 或 CDN 分发请求。 3. 缓存:Redis 预存热点数据,减少后端压力。 4. 限流与削峰:令牌桶或队列平滑流量。 5. 异步处理:MQ(如 Kafka)解耦写操作。 6. 快速扩容:云服务动态增加节点。
1. 问题分析
场景特点
- 流量极高:100 万 QPS,远超单机极限(假设单机 1-2 万 QPS)。
- 时间短:1-5 分钟,突发性强。
- 单节点瓶颈:
- CPU、内存、网络带宽、数据库连接耗尽。
- 响应时间暴增,系统崩溃。
计算
- 单机 1 万 QPS,需 100 台机器分担。
- 1 分钟 6000 万请求,需高效分发。
2. 处理方案
(1) 分布式部署
- 原理:
- 将服务部署到多节点,每节点处理部分流量。
- 实现:
- 部署 100 台服务器,每台 1 万 QPS。
- 用 Docker/Kubernetes 快速部署。
- 优点:
- 分担压力,提升总容量。
- 注意:
- 数据一致性(如库存)需锁或分布式事务。
(2) 负载均衡
- 原理:
- 前端均衡器分发请求到后端节点。
- 实现:
- Nginx:配置 upstream,轮询或 IP Hash。
upstream backend {
server 192.168.1.1:8080;
server 192.168.1.2:8080;
# ... 100 台
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
- CDN:静态资源和入口分发。
- 优点:
- 均匀分配流量,防止单点过载。
(3) 缓存优化
- 原理:
- 热点数据预存 Redis,减少数据库压力。
- 实现:
- 预加载活动数据(如库存)到 Redis。
Jedis jedis = new Jedis("localhost", 6379);
jedis.set("stock", "10000"); // 初始库存
- 查询走 Redis,写用原子操作(如
DECR
)。 - 优点:
- Redis 单机 10 万 QPS,集群更高。
- 注意:
- 缓存击穿:预热 + 限流。
(4) 限流与削峰
- 原理:
- 限制瞬时流量,平滑处理。
- 实现:
- 令牌桶:如 Sentinel,每秒放 100 万令牌。
- 队列:MQ(如 RabbitMQ)暂存请求,异步消费。
- 配置:
RateLimiter limiter = RateLimiter.create(1000000); // 100万QPS
if (limiter.tryAcquire()) {
// 处理请求
} else {
// 返回“稍后再试”
}
- 优点:
- 保护后端,避免雪崩。
(5) 异步处理
- 原理:
- 非核心操作(如日志、订单)异步化。
- 实现:
- 请求入 Kafka,消费者批量写数据库。
KafkaProducer producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>("orders", "order_data"));
- 优点:
- 解耦读写,降低瞬时压力。
(6) 快速扩容
- 原理:
- 云服务动态加节点。
- 实现:
- AWS Auto Scaling 或阿里云弹性伸缩。
- 预设镜像,1 分钟内扩容。
- 优点:
- 灵活应对突发流量。
3. 整体架构设计
图示
客户端 -> CDN/Nginx -> 多节点集群 -> Redis -> MQ -> DB
| | | | | |
100万QPS 分发 每节点1万QPS 缓存 异步 持久化
流程
- 用户请求 -> CDN/Nginx 分发到 100 台节点。
- 节点查 Redis 缓存(如库存)。
- 限流通过后,核心操作同步(如扣库存)。
- 非核心操作入 MQ,异步写 MySQL。
4. 关键点与优化
数据一致性
- 库存扣减:
- Redis
DECR
原子操作。 - 分布式锁(
SETNX
)防止超卖。 - 最终一致性:
- MQ 异步写 DB,失败重试。
性能瓶颈
- Redis:集群化,主从读写分离。
- DB:读写分离,分库分表。
降级预案
- 超限返回“活动火爆,请稍后”。
- 关闭非核心功能(如评论)。
5. 延伸与面试角度
- 容量估算:
- 单机 1 万 QPS,100 万需 100 台。
- Redis 集群 100 万 QPS 可扛。
- 实际案例:
- 秒杀:Redis + MQ + 限流。
- 直播:CDN + 缓存。
- 压测验证:
- JMeter 模拟 100 万 QPS,观察拐点。
- 面试点:
- 问“处理”时,提分布式和限流。
- 问“细节”时,提 Redis 原子性。
示例(Redis 扣库存)
Jedis jedis = new Jedis("localhost", 6379);
Long stock = jedis.decr("stock");
if (stock >= 0) {
// 成功扣减
} else {
// 库存不足
}
总结
100 万 QPS 靠分布式集群、负载均衡、缓存、限流和异步处理解决。Redis 扛读写,MQ 削峰,云服务快速扩容。面试时,可画架构图或提秒杀案例,展示设计能力。