Skip to content

秒杀时如何处理每秒上万次的下单请求?

在秒杀、抢购、春运抢票等场景下,会出现一种新的问题:

流量不是持续增长,而是在极短时间内突然爆发。

例如:

text
平时:
100 QPS

秒杀开始:
100000 QPS

这种流量甚至不是数据库的问题,而是整个系统都可能瞬间被打垮。

这时候就需要高并发系统中的另一个核心组件:

消息队列(Message Queue,MQ)

一、秒杀系统为什么容易崩

假设系统架构:

text
用户

下单服务

数据库

平时:

text
100 QPS

数据库可以轻松处理。

但秒杀开始:

text
10万用户
1秒内同时点击

变成:

text
100000 QPS

所有请求同时到达:

text
下单服务

数据库

结果:

text
线程打满
连接池耗尽
数据库崩溃

问题本质:

系统处理能力有限,但用户请求瞬间爆发。

例如:

text
系统能力:
1000单/秒

用户请求:
100000单/秒

两者严重不匹配。

二、消息队列解决什么问题

消息队列最核心的价值:

削峰填谷(Peak Shaving)

也就是:

把瞬间流量变成平稳流量。

原来:

text
100000请求

直接打数据库

现在:

text
100000请求

消息队列

消费者慢慢处理

数据库

相当于:

用户先排队。

系统按自己的能力处理。

例如:

text
瞬时:
100000订单

进入 MQ。

系统能力:

text
1000单/秒

那么:

text
100秒

处理完毕。

数据库始终只承受:

text
1000 TPS

不会被打爆。

三、什么是消息队列

消息队列本质上是:

一个存放消息的缓冲区。

例如:

text
生产者

MQ

消费者

生产者:

负责发送消息。

例如:

text
下单请求

消费者:

负责处理消息。

例如:

text
创建订单
扣减库存

MQ 位于中间。

负责:

text
存储
排队
转发

四、消息队列的工作流程

秒杀场景:

用户点击:

text
立即抢购

系统:

不直接下单。

而是:

text
写入MQ

例如:

json
{
  "userId":1001,
  "productId":1
}

然后:

立即返回:

text
排队中

后台消费者:

持续消费:

text
创建订单
扣减库存

因此:

用户请求与数据库操作彻底解耦。

五、消息队列的三大作用

文章强调:

很多人认为 MQ 只是削峰工具。

其实不止。

第一:异步处理

最常见用途。

例如:

用户注册:

text
创建用户
发送短信
发送邮件
积分发放

原来:

text
全部同步执行

耗时:

text
2秒

引入 MQ:

text
创建用户

立即返回

短信
邮件
积分

异步执行

响应时间:

可能变成:

text
100ms

第二:系统解耦

例如:

订单系统:

text
订单

库存

积分

优惠券

物流

如果全部直接调用:

系统耦合极高。

改为:

text
订单

MQ

库存
积分
物流

订单系统不关心:

谁消费消息。

因此:

新增功能:

text
订单完成

营销系统

只需新增消费者。

无需修改订单代码。

第三:削峰填谷

这是秒杀场景重点。

核心思想:

text
请求峰值

消息队列缓冲

平滑输出

六、为什么 MQ 能抗住流量洪峰

因为:

MQ 本身是:

内存 + 顺序写磁盘

数据库:

text
随机IO
事务
索引维护

很重。

MQ:

例如 Kafka:

text
顺序追加日志

极快。

因此:

Kafka 单机:

text
几十万QPS

很常见。

七、消息队列带来的问题

文章强调:

MQ 不是银弹。

引入后会增加系统复杂度。

八、消息丢失问题

例如:

text
订单消息

刚发送。

MQ 崩溃:

text
消息丢失

用户:

text
支付成功

但订单没创建。

因此:

MQ 必须支持:

text
持久化

九、重复消费问题

例如:

消费者:

text
创建订单

成功。

ACK 返回前:

消费者挂了。

MQ认为:

text
没处理成功

再次投递。

结果:

text
订单创建两次

因此:

消费者必须:

幂等。

即:

text
执行1次
执行10次
结果一样

十、消息积压问题

例如:

生产:

text
100000条/秒

消费:

text
1000条/秒

队列越来越大:

text
消息堆积

最终:

延迟越来越高。

因此:

需要:

text
增加消费者
扩容MQ

十一、消息顺序问题

例如:

账户操作:

text
充值100
扣款50

正确顺序:

text
+100
-50

如果乱序:

text
-50
+100

结果可能错误。

因此:

部分业务需要:

顺序消息。

十二、常见 MQ 产品

RabbitMQ

特点:

text
成熟
功能丰富

适合:

text
业务系统

Kafka

特点:

text
高吞吐
高性能

适合:

text
日志
大数据
秒杀

RocketMQ

阿里开源。

特点:

text
事务消息
顺序消息

大量用于:

text
电商系统

十三、秒杀系统经典架构

text
用户

Nginx

Redis预减库存

MQ

订单服务

MySQL

流程:

第一步

Redis判断:

text
库存是否存在

第二步

库存足够:

text
写MQ

第三步

消费者:

text
创建订单

这样:

数据库永远不会承受:

text
10万QPS

冲击。

十四、本章最核心的工程思想

消息队列解决的根本问题是:

系统处理能力与请求到达速度不匹配。

本质上:

MQ 就像银行排号机。

用户:

text
先领号

系统:

text
按能力处理

从而:

避免所有人同时冲向柜台。

十五、本章核心脉络

text
秒杀流量暴涨

数据库无法承受

引入消息队列


异步化
解耦
削峰



消息积压
重复消费
消息丢失



幂等
持久化
扩容



形成完整MQ架构

一句话总结

消息队列本质上是一种流量缓冲机制,通过将生产请求与实际处理过程解耦,实现异步处理、系统解耦和削峰填谷。在秒杀场景中,MQ 可以将瞬时数万甚至数十万次下单请求转化为系统可承受的稳定流量,从而保护数据库和核心业务系统不被流量洪峰压垮。

Released under the MIT License.