这是我参与【第五届青训营】伴学笔记创作活动的第9天
系统设计-秒杀业务
秒杀业务的特点
- 瞬时流量高
- 读多写少
- 实时性要求高
针对其瞬间高并发的特点,必须要做到限流 + 异步 + 缓存
秒杀业务流程
通过定时任务预先将需要上架的商品保存到redis中
秒杀商品上架
- 获取秒杀开始和结束的日期
- 获取秒杀商品信息
- 在 Redis 中保存秒杀场次信息
- 在 Redis 中保存秒杀活动关联的商品信息
- 设置秒杀商品的定时上架
- 获取处于秒杀的商品信息
秒杀
知识点
- 随机码-避免恶意秒杀
为了防止有用户在得知秒杀请求时,发送大量请求对商品进行秒杀或者直接通过软件来抢这些商品,可以采取随机码的方式。
即对每个要参加秒杀的商品,在秒杀活动开始的时候才放出这个随机值,只有通过正常提交请求的流程才可以获取,否则谁都无法得知随机码是多少,避免了恶意秒杀。
- 信号量-限流
库存秒杀不应该是实时去数据库扣库存,因为几百万请求进来的时候,如果都去扣,那会直接把数据库压垮。假设我们现在就一百个商品要被秒杀,哪怕放进来一百万请求,最终也只有一百个请求,能成功的去数据库扣掉库存。
所以我们可以提前在 redis 里边设置一个信号量,信号量保存了当前秒杀商品的库存信息,如果有用户想要秒杀这个商品,我们先去 redis 里边获取一个信号量,也就是库存减一操作,同时只有请求里携带了我们给秒杀商品设计的随机码 , 才可以来减信号量,如果能减成功,那就把这个请求放行,然后再去数据库扣掉库存。
- 幂等性保证-解决数据重复问题
布式系统里边,定时任务会出现这个问题
比如我们这有三台机器:A、B、C,代表我们同一个服务的三个副本,这三台机器,每台都有一个定时任务,因为它们都是同一段程序,定时任务的设置都一样,所以等时间一到,它们都会启动定时任务。一启动定时任务以后,因为将来它们要同时执行后面的上架代码,这就会导致同一个秒杀商品被重复上架3遍。所以不应该让每个机器都执行这个定时任务,应该只让一台机器去执行
解决:
①给定时任务加上分布式锁。通过redisson获取锁,获取到锁的机器才能执行,获取不到锁的机器,可以等获取到锁的机器执行失败,再次获取锁。
②接着就是判空,秒杀商品是否已经存在,如果存在这个key那么就不能再次上架保证幂等性。
③接着就是给商品信息判空。如果有商品信息的key那么也是不能够加入的
秒杀流程
思路
①点击抢购之后进入给秒杀服务,进行登录状态判断,秒杀服务取出当前秒杀商品,查询当前时间是不是在商品的活动时间之内。
②进行合法性校验(包括随机码是否正确,幂等性处理)
③校验信号量(即预设的抢购限额)是否在设定范围之内。
④接着就是秒杀成功需要在redis中保存信息,防止他再次发送请求来秒杀。
⑤最后就是通过redission取出信号量,进行定时扣减,如果扣减失败那么就不能发送下单消息,如果可以那么则创建订单,将订单信息发送到消息队列,让订单服务对队列进行一个监听操作。
总结
秒杀系统作为高并发实现的代表,充分使用了限流 、 异步 、缓存等技术,来保证可用性和稳定性。需要进一步思考秒杀系统的具体实现,借此更深一步理解对redis,rabbitmq,在实际开发中的运用。