秒杀系统总结

一、问题

  • 高并发
    • 缓存雪崩,缓存击穿,缓存穿透
  • 超卖
  • 重复下单问题

二、解决思路

1. 高并发

1.1 前端(用户层)

重复下单问题

  • 用户点击过快,重复提交。
  • 网络延时,用户重复提交。
  • 网络延时高的情况下某些框架自动重试,导致重复请求。
  • 用户恶意行为。

解决方法:

  • 网关拦截多开
  • 黑名单:
    • 网关层 增加ip黑名单
    • 后端: 加入临时黑名单 ,10分钟后才可继续操作,一小时允许一次跨时段弱校验。使用reids的list结构,过期时间一小时

限流 降级

  • 按钮时间变灰
  • 控制 参与次数
  • 秒杀链接加盐

静态页面或缓存

每隔一段时间更一次新,减少数据库压力

1.2 后端(服务端)

微服务架构 (热点隔离)

  • 服务单一职责
    • 业务隔离: 业务逻辑独立
    • 系统隔离: 秒杀、订务、 用户服务独立
    • 数据隔离: 独立的订单库、秒杀库
  • Nginx负载均衡、轮询(nginx端的接入能力配置应该不超过集群的事务处理能力)

消息队列

MQ,Redis等消息队列

Redis 高可用 (集群,主从同步、读写分离,哨兵机制,开启持久化)

  • Redis缓存
    • 库存预热

Mysql高可用(集群、读写分离)

2. 超卖(并发安全减库存)

  • 方案1: 数据库操作乐观锁

  • 方案2:利用Redis单线程 强制串行处理

    利用Redis 分布式锁,强制控制同一个商品处理请求串行化,缺点并发不高 ,处理比较慢,不适合抢购,高并发场景。用户体验差,但是减轻了数据库的压力。

  • 方案3 :redis + mq + mysql 保证库存安全,满足高并发处理,但相对复杂。

    利用Redis increment 的原子操作,保证库存安全,利用MQ保证高并发响应时间。但是事需要把库存的信息保存到Redis,并保证Redis 和 Mysql 数据同步。缺点是redis宕机后不能下单

3. 减库存与退库存

提交订单时减库存。用户选择提交订单,说明用户有强烈的购买欲望。生成订单会有一个支付时效,例如半个小时。超过半个小时后,系统自动取消订单,还库存。

超过订单有效时间、退单的解决方案:可

  • 设置定时检查
  • MQ消息延时队列

记录一些知识点

秒杀系统总结
秒杀系统总结

订单与库存涉及的几个重要知识

  • TCC 模型:Try/Confirm/Cancel:不使用强一致性的处理方案,最终一致性即可,下单减库存,成功后生成订单数据,如果此时由于超时导致库存扣成功但是返回失败,则通过定时任务检查进行数据恢复,如果本条数据执行次数超过某个限制,人工回滚。还库存也是这样。
  • 幂等性:分布式高并发系统如何保证对外接口的幂等性,记录库存流水是实现库存回滚,支持幂等性的一个解决方案,订单号+skuCode为唯一主键(该表修改频次高,少建索引)
  • 乐观锁:where stock + num>0
  • 消息队列:实现分布式事务 和 异步处理(提升响应速度)
  • redis:限制请求频次,高并发解决方案,提升响应速度
  • 分布式锁:防止重复提交,防止高并发,强制串行化
  • 分布式事务:最终一致性,同步处理(Dubbo)/异步处理(MQ)修改 + 补偿机制