题目
设计一个支持高并发秒杀活动的电商系统
信息
- 类型:问答
- 难度:⭐⭐⭐
考点
高并发处理,分布式系统设计,缓存策略,限流与降级,数据一致性
快速回答
设计高并发秒杀系统的核心要点:
- 分层削峰:通过CDN、网关、队列逐层过滤流量
- 读优化:使用Redis缓存商品库存和活动信息
- 写优化:采用异步扣减库存(Redis预减+MQ持久化)
- 限流防护:在网关层实现令牌桶/漏桶限流
- 熔断降级:对非核心服务(如推荐系统)降级
- 最终一致性:通过事务消息保证订单-库存一致性
1. 系统架构设计
分层架构:
- 客户端层:静态资源CDN缓存,按钮防重复点击
- 接入层:Nginx反向代理+Lua脚本实现限流
- 服务层:微服务拆分(秒杀服务独立部署)
- 数据层:Redis集群+MySQL分库分表
// 网关层限流示例(Sentinel)
@SentinelResource(value = "seckillFlow", blockHandler = "handleBlock")
public String seckillApi(String itemId) {
// 业务逻辑
}2. 核心难点解决方案
2.1 库存超卖问题
- Redis原子操作:使用Lua脚本保证原子性
- 分段扣减:将库存拆分为多个子库存段
-- Redis库存扣减Lua脚本
local key = KEYS[1]
local quantity = tonumber(ARGV[1])
if redis.call('get', key) >= quantity then
return redis.call('decrby', key, quantity)
else
return -1
end2.2 高并发写优化
- 请求进入RabbitMQ/Kafka削峰
- Worker服务异步处理订单
- 库存预扣:Redis扣减成功后再发MQ
// 伪代码:秒杀核心流程
public void handleSeckillRequest(String userId, String itemId) {
// 1. 校验用户资格(频率限制)
// 2. Redis预减库存(Lua脚本)
// 3. 发送MQ消息:包含秒杀凭证
// 4. 异步创建订单(Worker服务)
}3. 关键防护机制
3.1 限流策略
- 用户维度:同一用户10s内仅允许1次请求
- IP维度:滑动窗口限制异常IP
- 系统维度:QPS阈值动态调整
3.2 降级方案
- 一级降级:关闭实时库存显示
- 二级降级:排队机制(返回等待队列位置)
- 三级降级:静态化兜底页面
4. 数据一致性保障
最终一致性方案:
- Redis扣减库存成功
- 发送事务消息到RocketMQ
- 订单服务消费消息创建订单
- 定时任务核对库存与订单差异
// RocketMQ事务消息示例
transactionMQProducer.sendMessageInTransaction(msg, (arg) -> {
try {
// 执行本地事务(创建订单)
return LocalTransactionState.COMMIT_MESSAGE;
} catch (Exception e) {
return LocalTransactionState.ROLLBACK_MESSAGE;
}
});5. 常见错误与规避
- 错误1:直接查询数据库验证库存
规避:所有读操作走Redis缓存 - 错误2:同步调用支付服务
规避:支付操作异步化,秒杀成功即返回 - 错误3:单点限流
规避:分布式限流(Redis+Lua)
6. 扩展优化方向
- 库存预热:提前加载热点商品到本地缓存
- 动态扩容:Kubernetes+HPA自动扩缩容
- 作弊防控:风控系统实时检测机器人行为
- 压测优化:全链路压测+混沌工程