Redis分布式锁解决秒杀超卖问题

 更新时间:2022年07月13日 08:30:23   作者:艳梓  
本文主要介绍了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表达式

 到此这篇关于Redis分布式锁解决秒杀超卖问题的文章就介绍到这了,更多相关Redis秒杀超卖内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 初始Redis概念、特性、安装使用场景

    初始Redis概念、特性、安装使用场景

    Redis是一款高性能的内存键值对NoSQL数据库,支持多种数据结构及持久化机制,适用于缓存、消息队列等场景,被广泛应用于各大企业及开源系统,是开发运维必备技能,本文给大家介绍初始Redis概念、特性、安装使用场景,感兴趣的朋友一起看看吧
    2025-07-07
  • redis热key问题怎样解决

    redis热key问题怎样解决

    这篇文章主要介绍了redis热key问题怎样解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • 如何使用gradle将java项目推送至maven中央仓库

    如何使用gradle将java项目推送至maven中央仓库

    本文主要介绍了使用gradle将java项目推送至maven中央仓库,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Redis Key过期监听的配置详解

    Redis Key过期监听的配置详解

    这篇文章主要介绍了Redis Key过期监听配置,默认情况下在Windows系统中双击redis-server.exe用的是内置的配置文件,文中通过代码示例和图文讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-06-06
  • Redis连接池监控(连接池是否已满)与优化方法

    Redis连接池监控(连接池是否已满)与优化方法

    本文详细讲解了如何在Linux系统中监控Redis连接池的使用情况,以及如何通过连接池参数配置、系统资源使用情况、Redis命令监控、外部监控工具等多种方法进行检测和优化,以确保系统在高并发场景下的性能和稳定性,讨论了连接池的概念、工作原理、参数配置,以及优化策略等内容
    2024-09-09
  • SpringBoot集成Redis的思路详解

    SpringBoot集成Redis的思路详解

    Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。接下来通过本文给大家分享SpringBoot集成Redis的详细过程,感兴趣的朋友一起看看吧
    2021-10-10
  • Python利用redis限制用户重复刷新带来的数据问题

    Python利用redis限制用户重复刷新带来的数据问题

    在网站开发中,我们经常会遇到需要控制用户重复刷新页面的情况,本文就来介绍了Python利用redis限制用户重复刷新带来的数据问题,感兴趣的可以了解一下
    2024-03-03
  • Redis出现(error)NOAUTH Authentication required.报错的解决办法(秒懂!)

    Redis出现(error)NOAUTH Authentication required.报错的解决办法(秒懂!)

    这篇文章主要给大家介绍了关于Redis出现(error)NOAUTH Authentication required.报错的解决办法,对于 这个错误这通常是因为Redis服务器需要密码进行身份验证,但客户端没有提供正确的身份验证信息导致的,需要的朋友可以参考下
    2024-03-03
  • 使用Redis实现JWT令牌主动失效机制

    使用Redis实现JWT令牌主动失效机制

    JWT是一种轻量级的身份验证和授权机制,它是一种 JSON 格式的数据串,通常用于客户端和服务端之间的单点登录(Single Sign-On, SSO)场景,本文给大家介绍了如何使用Redis来实现JWT令牌主动失效机制,需要的朋友可以参考下
    2024-08-08
  • Redis Sentinel实现高可用配置的详细步骤

    Redis Sentinel实现高可用配置的详细步骤

    这篇文章主要介绍了Redis Sentinel实现高可用配置的详细步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09

最新评论