秒杀系统架构设计
系列导读:本篇将深入讲解秒杀系统的架构设计与核心实现。
文章目录
- 目录
- 一、秒杀系统特点
- 1.1 业务特点
- 1.2 技术挑战
- 二、架构设计
- 2.1 整体架构
- 2.2 流量削峰
- 三、核心实现
- 3.1 库存预热
- 3.2 秒杀核心逻辑
- 3.3 异步下单
- 四、防刷策略
- 4.1 验证码
- 4.2 限流
- 4.3 黑名单
- 总结
目录
- 一、秒杀系统特点
- 二、架构设计
- 三、核心实现
- 四、防刷策略
- 总结
一、秒杀系统特点
1.1 业务特点
┌─────────────────────────────────────────────────────────────┐ │ 秒杀系统特点 │ ├─────────────────────────────────────────────────────────────┤ │ 🌊 瞬时高并发:流量瞬间爆发 │ │ 📦 库存有限:商品数量有限 │ │ ⏰ 时间限制:固定时间段 │ │ 🎯 低价诱惑:吸引大量用户 │ └─────────────────────────────────────────────────────────────┘1.2 技术挑战
| 挑战 | 说明 |
|---|---|
| 高并发 | 瞬间流量巨大 |
| 超卖 | 库存不能超卖 |
| 防刷 | 防止机器刷单 |
| 稳定性 | 系统不能崩溃 |
二、架构设计
2.1 整体架构
┌─────────────────────────────────────────────────────────────┐ │ 秒杀架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 第一层:CDN 静态资源缓存 │ │ │ │ │ ▼ │ │ 第二层:Nginx 动静分离 + 限流 │ │ │ │ │ ▼ │ │ 第三层:网关层 认证 + 限流 │ │ │ │ │ ▼ │ │ 第四层:应用层 Redis 预减库存 + MQ 异步下单 │ │ │ │ │ ▼ │ │ 第五层:数据层 MySQL 持久化 │ │ │ └─────────────────────────────────────────────────────────────┘2.2 流量削峰
流量削峰策略: 1. 验证码:拉长请求时间 2. 答题:增加操作成本 3. 排队:请求队列化 4. 限流:丢弃多余请求三、核心实现
3.1 库存预热
// 秒杀开始前预热库存到 Redis@ServicepublicclassSeckillPreheatService{@AutowiredprivateStringRedisTemplateredisTemplate;publicvoidpreheat(LongseckillId,Integerstock){StringstockKey="seckill:stock:"+seckillId;StringusersKey="seckill:users:"+seckillId;// 设置库存redisTemplate.opsForValue().set(stockKey,String.valueOf(stock));// 清空已购买用户redisTemplate.delete(usersKey);}}3.2 秒杀核心逻辑
@ServicepublicclassSeckillService{@AutowiredprivateStringRedisTemplateredisTemplate;@AutowiredprivateRabbitTemplaterabbitTemplate;publicResultdoSeckill(LonguserId,LongseckillId){// 1. 检查是否重复购买StringusersKey="seckill:users:"+seckillId;BooleanisMember=redisTemplate.opsForSet().isMember(usersKey,userId);if(Boolean.TRUE.equals(isMember)){returnResult.fail("不能重复购买");}// 2. 预减库存(Lua 脚本保证原子性)StringstockKey="seckill:stock:"+seckillId;Stringscript="if tonumber(redis.call('GET', KEYS[1])) > 0 then "+" redis.call('DECR', KEYS[1]) "+" return 1 "+"else "+" return 0 "+"end";Longresult=redisTemplate.execute(newDefaultRedisScript<>(script,Long.class),Collections.singletonList(stockKey));if(result==null||result==0){returnResult.fail("库存不足");}// 3. 记录购买用户redisTemplate.opsForSet().add(usersKey,userId);// 4. 异步创建订单SeckillMessagemessage=newSeckillMessage(userId,seckillId);rabbitTemplate.convertAndSend("seckill.queue",message);returnResult.success("排队中,请稍后查询结果");}}3.3 异步下单
@ComponentpublicclassSeckillConsumer{@RabbitListener(queues="seckill.queue")publicvoidhandleSeckill(SeckillMessagemessage){try{// 创建订单orderService.createSeckillOrder(message.getUserId(),message.getSeckillId());}catch(Exceptione){log.error("秒杀订单创建失败",e);// 回滚库存stockService.rollback(message.getSeckillId());}}}四、防刷策略
4.1 验证码
// 验证码校验publicbooleanverifyCaptcha(StringcaptchaKey,Stringcaptcha){StringstoredCaptcha=redisTemplate.opsForValue().get(captchaKey);if(StringUtils.isEmpty(storedCaptcha)){returnfalse;}returnstoredCaptcha.equalsIgnoreCase(captcha);}4.2 限流
// 用户级限流publicbooleancheckUserLimit(LonguserId){Stringkey="seckill:limit:user:"+userId;Longcount=redisTemplate.opsForValue().increment(key);if(count==1){redisTemplate.expire(key,1,TimeUnit.SECONDS);}returncount<=5;// 每秒最多5次}// IP 级限流publicbooleancheckIpLimit(Stringip){Stringkey="seckill:limit:ip:"+ip;Longcount=redisTemplate.opsForValue().increment(key);if(count==1){redisTemplate.expire(key,1,TimeUnit.SECONDS);}returncount<=10;// 每秒最多10次}4.3 黑名单
// 黑名单检查publicbooleanisBlacklisted(LonguserId){returnredisTemplate.opsForSet().isMember("seckill:blacklist",userId);}总结
✅秒杀系统特点:高并发、库存有限、时间限制
✅架构设计:分层架构、流量削峰
✅核心实现:库存预热、预减库存、异步下单
✅防刷策略:验证码、限流、黑名单
下篇预告:支付系统架构设计
作者:刘~浪地球
系列:技术选型与实战(三)
更新时间:2026-04-24
