如何设计一个秒杀系统?

设计一个高并发、高可用的秒杀系统需要从 架构设计性能优化异常防护 三个维度综合考量。以下是经过大厂验证的完整方案,分为 6 个核心模块详细说明:


一、分层架构设计(百万级QPS)

客户端
CDN+静态化
API网关
秒杀服务集群
Redis集群
MQ削峰
订单服务
库存预热
MySQL分库分表
关键组件说明:
  1. CDN+静态化

    • 将秒杀页面静态化(HTML+CSS+JS)推送到CDN,减少源站压力。
    • 动态数据通过接口加载,如:/api/seckill/info?item_id=123
  2. 独立秒杀服务

    • 与主业务解耦,避免秒杀流量拖垮常规服务。
    • 无状态设计,支持快速水平扩展。
  3. 多级缓存

    • 本地缓存(Caffeine)→ Redis集群 → 数据库

二、库存管理(防超卖核心)

1. 库存预热
  • 活动开始前将库存加载到Redis:
    # Redis数据结构
    SET stock:item_123 1000  # 总库存
    SET stock:item_123:reserved 0  # 已预占
    
2. 预扣库存(Lua原子操作)
-- KEYS[1]:库存key, KEYS[2]:预占key, ARGV[1]:扣减量
local total = tonumber(redis.call('GET', KEYS[1]))
local reserved = tonumber(redis.call('GET', KEYS[2]))
if total - reserved >= tonumber(ARGV[1]) then
    redis.call('INCRBY', KEYS[2], ARGV[1])
    return 1  -- 成功
else
    return 0  -- 库存不足
end
3. 异步落库
  • 通过MQ异步更新数据库库存,保证最终一致:
    // RocketMQ消息结构
    public class StockMessage {
        private Long itemId;
        private Integer quantity;
        private String txId;  // 分布式事务ID
    }
    

三、流量控制(保护系统)

1. 分层限流
层级实现方式阈值示例
Nginxlimit_req_zone10,000 QPS/IP
网关Sentinel集群流控100,000 QPS
服务Semaphore信号量500 并发/节点
2. 请求合法性校验
  • 隐藏式验证码(行为验证):
    // 前端在提交前计算验证值
    const nonce = sha256(userId + itemId + 'salt');
    
  • 接口签名防刷:
    // 服务端校验
    if (!SHA256.matches(request.getNonce(), secretKey)) {
        throw new SecKillException("非法请求");
    }
    

四、高性能订单创建

1. 订单号生成
  • 使用改良雪花算法:
    时间戳(42bit) + 机器ID(10bit) + 序列号(12bit)
    
2. 订单异步化
// 1. 快速返回"处理中"
String orderToken = UUID.randomUUID().toString();
redisTemplate.opsForValue().set("order:token:" + orderToken, "PENDING", 5, TimeUnit.MINUTES);

// 2. MQ异步处理
rocketMQTemplate.asyncSend("seckill_order", 
    new OrderMessage(userId, itemId), 
    new SendCallback() { /* 处理结果 */ });

// 3. 前端轮询结果
GET /api/order/status?token=xxx
3. 分库分表策略
  • 按用户ID哈希分片:order_db_{user_id % 16}.order_tab_{user_id % 64}

五、容灾与降级

1. 熔断策略
# Sentinel配置
spring:
  cloud:
    sentinel:
      rules:
        - resource: createOrder
          grade: QPS
          count: 5000
          strategy: Direct
          controlBehavior: Throttling
2. 降级方案
  • 读降级:直接返回缓存中的静态库存(可能不准确)
  • 写降级:关闭非核心功能(如积分抵扣)
3. 数据恢复
  • 定时对账任务修复异常订单:
    UPDATE orders SET status='FAILED' 
    WHERE status='PENDING' AND created_at < NOW() - INTERVAL 30 MINUTE;
    

六、监控体系

1. 核心监控项
指标工具报警阈值
Redis库存同步延迟Prometheus>5s
MQ积压消息数RocketMQ Console>10,000
订单创建成功率Grafana<99%
2. 全链路压测
  • 使用JMeter模拟真实流量:
    jmeter -n -t seckill_test.jmx -l result.jtl -Jthreads=10000 -Jrampup=60
    

技术选型建议

场景推荐技术栈
流量接入层Nginx + OpenResty + Lua
缓存层Redis Cluster + Pipelining
消息队列RocketMQ(事务消息)
数据存储MySQL(分库分表)+ TiDB(可选)
监控报警Prometheus + Grafana + ELK

典型秒杀流程

  1. 用户:进入静态页面 → 获取动态令牌 → 提交请求
  2. 系统:校验令牌 → 预扣库存 → 异步创建订单 → 返回结果
  3. 支付:15分钟内未支付则释放库存

通过以上设计,系统可支持 百万级QPS,保证 99.95%可用性。实际落地时需根据业务特点调整细节,例如:

  • 奢侈品秒杀:增加风控层级
  • 食品秒杀:强化库存回补机制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java干货仓库

觉得写的不错,就给博主投币吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值