优秀方案我来告诉你
商品秒杀的场景,我们需要防止库存超卖或者重复扣款等并发问题,我们通常需要使用分布式锁,来解决共享资源竞争导致数据不一致的问题。 以手机秒杀的场景为例子,在抢购的过程中通常我们有三个步骤: 扣掉对应商品的库存;2. 创建商品的订单;3. 用户支付。 对于这样的场景我们就可以采用分布式锁的来解决,比如我们在用户进入秒杀 “下单“ 链接的过程中,我们可以对商品库存进行加锁,然后完成扣库存和其他操作,操作完成后。释放锁,让下一个用户继续进入保证库存的安全性;也可以减少因为秒杀失败,导致 DB 回滚的次数。整个流程如下图所示:对于锁的粒度要根据具体的场景和需求来权衡。 三种分布式锁对于 Zookeeper 的分布式锁实现,主要是利用 Zookeeper 的两个特征来实现:
非公平锁对于非公平锁,我们在加锁的过程如下图所示。其实上面的实现有优点也有缺点: 优点: 实现比较简单,有通知机制,能提供较快的响应,有点类似 ReentrantLock 的思想,对于节点删除失败的场景由 Session 超时保证节点能够删除掉。 缺点: 重量级,同时在大量锁的情况下会有 “惊群” 的问题。 “惊群” 就是在一个节点删除的时候,大量对这个节点的删除动作有订阅 Watcher 的线程会进行回调,这对Zk集群是十分不利的。所以需要避免这种现象的发生。 解决“惊群”:为了解决“惊群“问题,我们需要放弃订阅一个节点的策略,那么怎么做呢?
公平锁: 如上借助于临时顺序节点,可以避免同时多个节点的并发竞争锁,缓解了服务端压力。缺点: 对于读写场景来说,无法解决一致性的问题,如果读的时候也去获取锁的话,这样会导致性能下降,对于这样的问题,我们可以通过读写锁来实现如类似 jdk 中的 ReadWriteLock 读写锁实现对于读写锁的特点:读写锁在如果多个线程都是在读的时候,是可以并发读的,就是一个无锁的状态,如果有写锁正在操作的时候,那么读锁需要等待写锁。在加写锁的时候,由于前面的读锁都是并发,所以需要监听最后一个读锁完成后执行写锁。步骤如下:
(编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |