• Redis分布式锁——秒杀超卖


    分布式锁应用场景
    在这里插入图片描述
    秒杀环境下:订单服务从库存中心拿到库存数,如果库存总数大于0,则进行库存扣减,并创建订单
    订单服务负责创建订单
    库存服务负责扣减库存
    在这里插入图片描述
    模拟用户访问库存
    在这里插入图片描述
    在这里插入图片描述
    多线程并发访问,出现超卖问题,线程不安全。没有保证原子性

    单体锁的分类
    单体应用锁指的是只能在 一个JVM 进程内有效的锁。我们把这种锁叫做单体应用锁

    • synchronized锁
    • ReentrantLock锁
      一个 Tomcat 可以看作是一个JVM进程,当大量请求并发到系统时,所有的请求都落在这唯一的一个Tomcat上,如果某些请求方法是需要加锁的,比如:秒杀扣减库存,是可以满足需求的,但是随着访问量的增加,导致一个tomcat 难以支撑,这时我们必然就是集群部署Tomcat ,使用多个 Tomcat 共同支撑整个系统。
      在这里插入图片描述
      我们看到系统中存在两个Tomcat,我们加的锁是JDK提供的锁,这种锁只能在 一个JVM 下起到作用,也就是在一个Tomcat内是没有问题的。当存在两个或两个以上的Tomcat时,大量的并发请求分散到不同的Tomcat上,在每一个Tomcat中都可以防止并发的产生,但是在多个Tomcat之间,每个Tomcat中获得锁的这个请求,又产生了并发,从而产生超卖现象。这也就是单体应用锁的局限性了,它只能在一个JVM内加锁,所以单体锁只能锁住单体环境,是锁不住分布式环境或集群环境的。

    分布式锁核心逻辑
    分布式锁的核心逻辑就是在多个服务中设置一个公共的资源,在公共资源中设置锁,供多个服务去同时抢夺锁资源,一旦其中一个线程抢夺成功,其他线程就进入自旋状态,不同的尝试访问获取锁资源,在获取锁资源的线程执行完相应的逻辑以后就会释放锁资源,其他线程就可以获取锁资源。
    在这里插入图片描述
    在这里插入图片描述
    分布式锁实现的问题——死锁和解决
    死锁:
    如果某个线程在执行锁逻辑过程中宕机,导致没有删除锁
    解决:

    • 添加过期时间
      在这里插入图片描述
      因为是非原子性添加过期时间,可能导致在添加过期时间之前就出现宕机现象,此时依旧进入死锁状态。
    • 原子性添加过期时间
      在这里插入图片描述
      Redis解决删除别人锁的问题
      删除别人锁:
      当有线程A进入后由于超时,有其他线程B进入,此时redis中的锁是线程B的,而原来的线程A接着执行,线程A删除了别人的锁。

    删除别人锁解决:
    ①给当前线程绑定一个局部变量uuid,由于每个线程都有一份自己的局部变量,那么线程和局部变量绑定之后,我们在删除锁之前判断一下,当前这把锁是不是自己的载进行删除
    ②使用lua表达式进一步解决
    在这里插入图片描述
    上述方案还是存在问题,在线程A自己的uuid刚好与redis的uuid比较完,正准备删除的时候过期,这时候B线程进入,此时的redisuuid就不是线程A的了,此时还是会存在删除别人锁的问题。
    这是由于在拿锁、比较锁和删除锁的过程中并不是原子性的操作。解决此问题可以使用lua表达式
    在这里插入图片描述

  • 相关阅读:
    MS1205N激光测距用高精度时间测量(TDC)电路
    前端经典面试题 | 闭包的作用和原理
    如何使用Python进行数据可视化:Matplotlib和Seaborn指南【第123篇—Matplotlib和Seaborn指南】
    SpringBoot自动配置原理及启动流程
    WordPress建站入门教程:小皮面板phpstudy如何安装PHP和切换php版本?
    【花书笔记|PyTorch版】手动学深度学习7:模型选择、欠拟合和过拟合
    算法D31 | 贪心算法1 | 455.分发饼干 376. 摆动序列 53. 最大子序和
    中间件——爬取网易新闻内容
    AI 驱动的医疗变革:迈向未来医疗新生态
    宝塔面板是干什么的?有哪些典型的功能作用?
  • 原文地址:https://blog.csdn.net/xiaowanziddd/article/details/125583692