优惠券秒杀逻辑总结

整体业务逻辑
上图为整体逻辑
该业务较为复杂,高并发情况下要考虑非常多的角度

秒杀业务

先考虑两部分,一部分就是一个人只能下一单

一、一人一单、防止超卖

一人一单,一个人只能下一单

根据用户id上synchronized锁,order的ID为了保证数据隐私最好使用算法生成,类似于ID的雪花算法或者UUID算法,锁要控制其粗粒度大小,不能让过多的内容上到锁,不然大量的线程都会锁在线程外面,全部被排在锁的外面。根据用户ID下单,锁的也是(业务名字+用户ID)(这样最小化了锁的粗粒度),在对数据库进行操作时候,用乐观锁的思想,在对库存进行操作的时候判断库存是否和当时进来的时候一样,一样说明了被别的线程改过了说明线程不安全直接SQL语句报错。在乐观锁和悲观锁的考虑上,如果直接上悲观锁就会导致大量的用户直接的访问失败不合适。实际上很多用户是可以买的,只是因为语句被上了锁就无法访问不行。

一个好的锁应该能够在一定时间内重复被请求访问,可重新,可短期重复被请求访问。同时,需要可以超时释放,如果业务仍在执行也要能保证安全。在分布式中要保证主从一致性问题。

二、分布式情况下如何保证

分布式锁

首先,分布式锁先要考虑一个问题就是分布式锁一定要所有服务都能访问一把锁,这把锁就可以是Redis的锁,Redis是单线程直接存在线程之中访问快能够最大程度上提升整体的访问效率。

分布式锁中会出现误删问题,这个和单线程是不一样的,因为多线程之中可能有多个服务,他们持着一个

其实如果加的锁是业务名字+用户ID的话不管单例还是集群都会出现锁的误删,单例中没有考虑主要是因为有synchronized锁和乐观锁把所有问题解决了,没有用到Redis锁,锁的时候根本不看名字的,但是集群中哪怕对比线程ID都会出意外,两个计算机可能会有相同的线程ID访问同一个业务就会出现问题。最好的解决办法还是全局唯一ID,来个UUID解决一切。

为了保证删除锁时候的原子性,加入Lua脚本

Redission,包里面提供了大量非常厉害的锁,红锁,可重入锁等等,这些锁都非常强大

异步秒杀

在增加优惠券的同时将券直接将优惠券个数存储在redis中,等需要获取时候,直接从库里扣,对用户和这个券ID直接标记,如果过来没有找到这个用户,将下单成功的消息直接扔到消息队列里

消息队列可以用自带的也可以用市面上非常获得RocketMQ还有RabbitMQ

进去以后执行流程再像上面一样

最后的事务如果要加的话
由于类的代理问题,所以要用AOPcontext获取当前代理类,再用proxy调用自身函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值