秒杀系统
超卖
问题:实际售卖的商品数量超过了实际库存量,可能导致系统错误、用户体验下降以及商家损失等问题。秒杀系统中的超卖问题是比较常见的挑战,因为瞬时高并发情况下,多个用户同时购买同一商品可能会导致库存数量不一致。
解决:
将商品的库存缓存到数据库中,收到秒杀请求,先在Redis中进行预减,Redis库存不足,直接返回秒杀失败。如果有库存将请求放入异步消息队列中(RabbitMQ)中。
通过使用乐观锁或悲观锁来保护库存操作,以防止多个用户同时减少库存,确保只有一个用户能够成功减库存。乐观锁通常使用版本号或时间戳来实现,而悲观锁则是通过数据库的锁机制。
高并发
问题:大量用户会在短时间内争相购买有限数量的商品。缓存击穿、缓存穿透、缓存雪崩,导致大量请求打到数据库、缓存一致性等问题。
解决:
缓存一致性:使用canal组件实现,解析数据库的二进制日志(binlog)来获取数据库的变更数据,并通过网络协议将数据传输到订阅者端。更新数据库后立即删除缓存,下一次请求找不到缓存数据,查询数据同步到缓存。
缓存预热:
将商品信息提前缓存到Redis。
异步下单:
在判断缓存中还存在库存时,给mq发生消息,然后给用户返回“秒杀成功,正在创建订单”,让订单服务监听mq,异步进行订单的创建、扣减库存等操作,防止请求阻塞等待订单创建完成才给用户返回结果。
限流:
令牌桶算法:令牌桶算法是一种基于令牌的限流算法。系统会维护一个令牌桶,每个令牌代表 一个请求的处理能力。当用户发起请求时,需要从令牌桶中获取一个令牌,如果令牌桶为空,则该请求被拒绝。通过控制令牌的生成速率和桶的容量,可以限制系统的请求处理能力。
漏桶算法:漏桶算法是一种基于漏桶的限流算法。系统会维护一个固定容量的漏桶,每个请求都会以恒定的速率流入漏桶,如果漏桶已满,则多余的请求会被丢弃。通过控制漏桶的容量和漏水速率,可以限制系统的请求处理速度。
计数器限流:计数器限流是一种简单有效的限流策略。系统会维护一个计数器,记录单位时间内的请求次数。当请求次数超过设定的阈值时,后续的请求会被暂时拒绝。可以根据系统的处理能力和预期的并发量来设置合适的阈值。
定时关单 :
当订单创建成功,给mq交换机发生信息(订单实体对象),交换机根据路由键转发到延迟队列(rabbitMQ没有延迟队列,可以通过死信队列实现,设置ttl,过期进入死信队列,消费者监听死信队列或者社区插件),关单服务监听死信队列,拿到消息后判单订单状态,如果是带支付状态就进行关单,把订单状态设置为已取消。
数据库
针对秒杀系统的数据库问题,应该单独设计秒杀数据库,防止秒杀系统的高并发拖垮整个网站。数据库包含秒杀用户表、商品信息表、秒杀商品表、秒杀订单表。
- 本文作者:chen
- 本文链接:http://suft.top/2023/12/16/%E7%A7%92%E6%9D%80%E7%B3%BB%E7%BB%9F/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!