秒杀时如何处理每秒上万次的下单请求?
在秒杀、抢购、春运抢票等场景下,会出现一种新的问题:
流量不是持续增长,而是在极短时间内突然爆发。
例如:
平时:
100 QPS
秒杀开始:
100000 QPS这种流量甚至不是数据库的问题,而是整个系统都可能瞬间被打垮。
这时候就需要高并发系统中的另一个核心组件:
消息队列(Message Queue,MQ)
一、秒杀系统为什么容易崩
假设系统架构:
用户
↓
下单服务
↓
数据库平时:
100 QPS数据库可以轻松处理。
但秒杀开始:
10万用户
1秒内同时点击变成:
100000 QPS所有请求同时到达:
下单服务
↓
数据库结果:
线程打满
连接池耗尽
数据库崩溃问题本质:
系统处理能力有限,但用户请求瞬间爆发。
例如:
系统能力:
1000单/秒
用户请求:
100000单/秒两者严重不匹配。
二、消息队列解决什么问题
消息队列最核心的价值:
削峰填谷(Peak Shaving)
也就是:
把瞬间流量变成平稳流量。
原来:
100000请求
↓
直接打数据库现在:
100000请求
↓
消息队列
↓
消费者慢慢处理
↓
数据库相当于:
用户先排队。
系统按自己的能力处理。
例如:
瞬时:
100000订单进入 MQ。
系统能力:
1000单/秒那么:
100秒处理完毕。
数据库始终只承受:
1000 TPS不会被打爆。
三、什么是消息队列
消息队列本质上是:
一个存放消息的缓冲区。
例如:
生产者
↓
MQ
↓
消费者生产者:
负责发送消息。
例如:
下单请求消费者:
负责处理消息。
例如:
创建订单
扣减库存MQ 位于中间。
负责:
存储
排队
转发四、消息队列的工作流程
秒杀场景:
用户点击:
立即抢购系统:
不直接下单。
而是:
写入MQ例如:
{
"userId":1001,
"productId":1
}然后:
立即返回:
排队中后台消费者:
持续消费:
创建订单
扣减库存因此:
用户请求与数据库操作彻底解耦。
五、消息队列的三大作用
文章强调:
很多人认为 MQ 只是削峰工具。
其实不止。
第一:异步处理
最常见用途。
例如:
用户注册:
创建用户
发送短信
发送邮件
积分发放原来:
全部同步执行耗时:
2秒引入 MQ:
创建用户
↓
立即返回
短信
邮件
积分
↓
异步执行响应时间:
可能变成:
100ms第二:系统解耦
例如:
订单系统:
订单
↓
库存
↓
积分
↓
优惠券
↓
物流如果全部直接调用:
系统耦合极高。
改为:
订单
↓
MQ
↓
库存
积分
物流订单系统不关心:
谁消费消息。
因此:
新增功能:
订单完成
↓
营销系统只需新增消费者。
无需修改订单代码。
第三:削峰填谷
这是秒杀场景重点。
核心思想:
请求峰值
↓
消息队列缓冲
↓
平滑输出六、为什么 MQ 能抗住流量洪峰
因为:
MQ 本身是:
内存 + 顺序写磁盘
数据库:
随机IO
事务
索引维护很重。
MQ:
例如 Kafka:
顺序追加日志极快。
因此:
Kafka 单机:
几十万QPS很常见。
七、消息队列带来的问题
文章强调:
MQ 不是银弹。
引入后会增加系统复杂度。
八、消息丢失问题
例如:
订单消息刚发送。
MQ 崩溃:
消息丢失用户:
支付成功但订单没创建。
因此:
MQ 必须支持:
持久化九、重复消费问题
例如:
消费者:
创建订单成功。
ACK 返回前:
消费者挂了。
MQ认为:
没处理成功再次投递。
结果:
订单创建两次因此:
消费者必须:
幂等。
即:
执行1次
执行10次
结果一样十、消息积压问题
例如:
生产:
100000条/秒消费:
1000条/秒队列越来越大:
消息堆积最终:
延迟越来越高。
因此:
需要:
增加消费者
扩容MQ十一、消息顺序问题
例如:
账户操作:
充值100
扣款50正确顺序:
+100
-50如果乱序:
-50
+100结果可能错误。
因此:
部分业务需要:
顺序消息。
十二、常见 MQ 产品
RabbitMQ
特点:
成熟
功能丰富适合:
业务系统Kafka
特点:
高吞吐
高性能适合:
日志
大数据
秒杀RocketMQ
阿里开源。
特点:
事务消息
顺序消息大量用于:
电商系统十三、秒杀系统经典架构
用户
↓
Nginx
↓
Redis预减库存
↓
MQ
↓
订单服务
↓
MySQL流程:
第一步
Redis判断:
库存是否存在第二步
库存足够:
写MQ第三步
消费者:
创建订单这样:
数据库永远不会承受:
10万QPS冲击。
十四、本章最核心的工程思想
消息队列解决的根本问题是:
系统处理能力与请求到达速度不匹配。
本质上:
MQ 就像银行排号机。
用户:
先领号系统:
按能力处理从而:
避免所有人同时冲向柜台。
十五、本章核心脉络
秒杀流量暴涨
↓
数据库无法承受
↓
引入消息队列
↓
异步化
解耦
削峰
↓
消息积压
重复消费
消息丢失
↓
幂等
持久化
扩容
↓
形成完整MQ架构一句话总结
消息队列本质上是一种流量缓冲机制,通过将生产请求与实际处理过程解耦,实现异步处理、系统解耦和削峰填谷。在秒杀场景中,MQ 可以将瞬时数万甚至数十万次下单请求转化为系统可承受的稳定流量,从而保护数据库和核心业务系统不被流量洪峰压垮。