企业实战之如何设计一个秒杀系统?

大哥大姐们有没有人讲详细点的我想问下,企业实战之如何设计一个秒杀系统?
最新回答
人已去梦依旧*

2026-08-09 11:36:51

设计一个秒杀系统需要综合考虑高并发、数据一致性、系统稳定性和用户体验等多个方面,以下是核心设计要点和技术方案:

一、业务流程与核心特性

秒杀业务具备以下特性:

  • 倒计时开场:到点开通购买,时间由服务器端同步和判断。
  • 价格便宜,库存少:商品数量有限,价格极具吸引力。
  • 用户限制:通常限制每个用户只能购买一个商品。

常规秒杀业务流程与普通购物流程类似:

  • 查询商品详情
  • 点击购买,校验库存
  • 扣库存,创建订单
  • 去支付
二、各环节设计要点1. 查看商品详情
  • 高并发处理:秒杀前用户会频繁刷新商品页面,导致请求量激增。可采用页面静态化技术,将商品详情页面生成静态HTML,减少服务器实时渲染压力。
  • 倒计时同步:倒计时效果由客户端实现,但时间需同步服务器端,客户端每隔几分钟同步一次时间并重新倒计时。秒杀时间是否已到由服务器端判断,而非客户端时间。

2. 校验库存
  • 缓存库存:大量请求直接走数据库校验库存不可行,应将商品库存放到缓存中,分布式系统推荐使用Redis。
  • 缓存时机:通过后台管理系统,在添加秒杀商品并点击【上线发布】按钮时,将库存信息缓存到Redis。

3. 扣库存
  • 超卖问题:直接先检查库存再扣库存的代码在并发情况下会出现超卖。例如,剩余库存为1时,2个线程同时通过库存检查,先后执行扣库存操作,会导致库存变为-1。
  • 解决方案:

    SQL优化:修改SQL语句,在update语句的where条件中加入stock > 0,利用行锁保证同一时间只有一个线程能执行更新操作,避免超卖。

    DBUtils.ExecuteSql(" update goods set stock = stock - 1 where goodId = ? and stock > 0", goodId);

    分布式锁:使用分布式排他锁或乐观锁解决并发问题。

4. 何时扣库存
  • 方案选择:

    下单减库存:买家下单后立即减库存。但可能存在恶意用户将商品全部下单却不付款,导致正常用户无法购买。

    付款减库存:买家下单后不立即减库存,等付款后才减。但可能出现大量用户下单,付款时只有部分用户能成功,用户体验差。

  • 推荐方案:秒杀场景下一般选择下单减库存,同时设置一定的支付时间(如半小时),超过不支付则失效订单并回收库存。
5. 用户标记
  • 风控措施:加入风控系统,监控下单不付款的用户。若超过一定阈值,将该用户打上标记并归入黑名单。同时限制每个用户的购买数量,规避恶意下单。
6. 分布式限流
  • 限流必要性:秒杀商品数量有限,大量无效请求会增加系统压力。例如,100万用户抢100个商品,90%的请求是无效的。
  • 限流方案:只允许一定数量的用户(如5000个,根据业务评估)进入业务系统,其他请求直接返回。可采用Nginx限流、业务系统的计数器法、漏斗法、令牌法等,一般基于Redis进行令牌限流。

7. 异步化
  • 思路由来:即使有限流机制,仍可能有大量请求进入业务系统。例如,5000个并发操作MySQL数据库,一般MySQL并发量在500左右,难以承受。
  • 异步处理方案:将下单请求进入消息队列(如RabbitMq、RocketMq),让订单消费服务慢慢处理,将并发同步请求改为串行异步。
  • 前端改造:前端在下单时无法立刻得到结果,需显示【抢购中...】状态页面,并定时轮询下单结果,提升系统吞吐量,降低压力。
三、设计核心思想总结
  • 尽量拦截请求在最外层:通过限流等手段减少进入业务系统的请求数量。
  • 保护数据库资源:采用缓存技术,减少数据库访问压力。
  • 同步操作异步化:将高并发同步操作改为异步处理,提高系统吞吐量。
  • 尽早失败:对无效请求或异常情况尽早返回失败结果,保护业务系统稳定运行。