Spring Boot 集成Redisson实现分布式锁

Redission配置参数说明 server: servlet: context-path: / port: 8888 spring: application: name: lizz-boot redis: timeout: 1000 # 连接超时时间(毫秒) cluster: nodes: - 10.2.55.107:6379 - 10.2.55.107:6380 - 10.2.55.107:6381 - 10.. 阅读详情

分布式锁实现

引入jar包

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
      <exclusion>
         <groupId>io.lettuce</groupId>
         <artifactId>lettuce-core</artifactId>
      </exclusion>  
    </exclusions>
   </dependency>

      <dependency>
         <groupId>org.redisson</groupId>
         <artifactId>redisson-spring-boot-starter</artifactId>
         <version>3.13.6</version>
     </dependency>

说明:关于集成Redisson,我们需要注意与Spring Boot的版本对应。具体对应的关系如下:

注意:3.13.6对应的Spring Boot的版本为2.3.0,而redis-spring-data为redis-spring-data-23。我们可以通过查看pom文件的引用从而得到依赖关系。

Redisson的配置

application.yml中引入redisson.yml配置

  redis:
    redisson:
      file: classpath:redisson.yml


redisson.yml配置

singleServerConfig:
  password: xxxx
  address: "redis://127.0.0.1:6379"
  database: 1
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.FstCodec> {}
transportMode: "NIO"

说明:本文配置的是单机环境,如果需要配置集群环境,可以采用如下配置:

 clusterServersConfig:
          idleConnectionTimeout: 10000
          connectTimeout: 10000
          timeout: 3000
          retryAttempts: 3
          retryInterval: 1500
          failedSlaveReconnectionInterval: 3000
          failedSlaveCheckInterval: 60000
          password: null
          subscriptionsPerConnection: 5
          clientName: null
          loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
          subscriptionConnectionMinimumIdleSize: 1
          subscriptionConnectionPoolSize: 50
          slaveConnectionMinimumIdleSize: 24
          slaveConnectionPoolSize: 64
          masterConnectionMinimumIdleSize: 24
          masterConnectionPoolSize: 64
          readMode: "SLAVE"
          subscriptionMode: "SLAVE"
          nodeAddresses:
          - "redis://127.0.0.1:6379"
          - "redis://127.0.0.1:6380"
          - "redis://127.0.0.1:6381"
          scanInterval: 1000
          pingConnectionInterval: 0
          keepAlive: false
          tcpNoDelay: false
        threads: 6
        nettyThreads: 12
        codec: !<org.redisson.codec.MarshallingCodec> {}
        transportMode: "NIO"

封装Redisson工具类

@Component
public class RedissonLockUtil
{
    private static final Logger logger = LoggerFactory.getLogger(RedissonLockUtil.class);

        @Autowired
        private RedissonClient redissonClient;

        /**
         * 加锁
         * @param lockKey
         * @return
         */
        public RLock lock(String lockKey) 
        {
            RLock lock = redissonClient.getLock(lockKey);
            return lock;
        }

        /**
         * 公平锁
         * @param key
         * @return
         */
        public RLock fairLock(String key) 
        {
            return redissonClient.getFairLock(key);
        }

        /**
         * 带超时的锁
         * @param lockKey
         * @param timeout 超时时间 单位:秒
         */
        public RLock lock(String lockKey, int timeout) 
        {
            RLock lock = redissonClient.getLock(lockKey);
            lock.lock(timeout, TimeUnit.SECONDS);
            return lock;
        }

        /**
         * 读写锁
         * @param key
         * @return
         */
        public RReadWriteLock readWriteLock(String key) {
            return redissonClient.getReadWriteLock(key);
        }

        /**
         * 带超时的锁
         * @param lockKey
         * @param unit 时间单位
         * @param timeout 超时时间
         */
        public RLock lock(String lockKey, TimeUnit unit ,int timeout) {
            RLock lock = redissonClient.getLock(lockKey);
            lock.lock(timeout, unit);
            return lock;
        }

        /**
         * 加锁
         * @param key
         * @param supplier
         * @return
         */
        public <T> T lock(String key, Supplier<T> supplier) {
            RLock lock = lock(key);
            try {
                lock.lock();
                return supplier.get();
            } finally {
                if (lock != null && lock.isLocked()) {
                    lock.unlock();
                }
            }
        }

        /**
         * 尝试获取锁
         * @param lockKey
         * @param waitTime 等待时间
         * @param leaseTime 自动释放锁时间
         * @return
         */
        public  boolean tryLock(String lockKey, int waitTime, int leaseTime) {
            RLock lock = redissonClient.getLock(lockKey);
            try {
                return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                return false;
            }
        }

        /**
         * 尝试获取锁
         * @param lockKey
         * @param unit 时间单位
         * @param waitTime 等待时间
         * @param leaseTime 自动释放锁时间
         * @return
         */
        public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
            RLock lock = redissonClient.getLock(lockKey);
            try {
                return lock.tryLock(waitTime, leaseTime, unit);
            } catch (InterruptedException e) {
                return false;
            }
        }

        /**
         * 释放锁
         * @param lockKey
         */
        public void unlock(String lockKey) {
            RLock lock = redissonClient.getLock(lockKey);
            lock.unlock();
        }

        /**
         * 释放锁
         * @param lock
         */
        public void unlock(RLock lock) 
        {
            lock.unlock();
        }
    }  

模拟秒杀扣减库存

 public int lockStock()
    {
        String lockKey="lock:stock";
        String clientId = UUID.randomUUID().toString();

        //加锁
        RLock lock=redissonLockUtil.lock(lockKey);
        lock.lock();

        try
        {
           logger.info("加锁成功 clientId:{}",clientId);
           int stockNum= Integer.valueOf((String)redisUtil.get("seckill:goods:stock"));
           if(stockNum>0)
           {   
              stockNum--;
              redisUtil.set("seckill:goods:stock",String.valueOf(stockNum));
              logger.info("秒杀成功,剩余库存:{}",stockNum);
           }
           else
           {
              logger.error("秒杀失败,剩余库存:{}", stockNum);
           }
           //获取库存数量
           return stockNum;
        }
        catch (Exception e)
        {
           logger.error("decry stock eror",e);
        }
        finally
        {
            if(lock!=null)
            {
                lock.unlock(); 
            }
        }
        return 0;
    }

测试代码

@RequestMapping("/redisLockTest")
    public void redisLockTest()
    {
        // 初始化秒杀库存数量
        redisUtil.set("seckill:goods:stock", "10");

        List<Future> futureList = new ArrayList<>();

        //多线程异步执行
        ExecutorService executors = Executors.newScheduledThreadPool(10);
        //
        for (int i = 0; i < 30; i++)
        {
            futureList.add(executors.submit(this::lockStock));

            try 
            {
               Thread.sleep(100);
            } 
            catch (InterruptedException e) 
            {
               logger.error("redisLockTest error",e);
            }
        }

        // 等待结果,防止主线程退出
        futureList.forEach(t -> {
            try 
            {
                int stockNum =(int) t.get();
                logger.info("库存剩余数量:{}",stockNum);
            }
            catch (Exception e)
            {
               logger.error("get stock num error",e);
            }
        });
    }

执行结果如下:

总结

本文针对Spring Boot集成Redisson的基本使用。

解决Redisson中“Unsupported protocol version 34”错误 在使用Redisson客户端连接Redis时,你可能会遇到这样的异常。这种错误通常与Redisson使用的序列化/反序列化方法(Codec)有关,尤其是在升级或更改Redisson版本后更为常见。 阅读详情

相关推荐

优雅实现分布式锁:Spring Boot自定义注解与Redisson的集成

本文将介绍如何使用Spring Boot自定义注解与Redisson集成,实现一种优雅的分布式锁架构。至此,我们已经完成了Spring Boot自定义注解与Redisson集成的优雅分布式锁架构。通过使用自定义注解和AOP拦截器,我们可以轻松地为任意方法加上分布式锁,确保并发访问的安全性。当方法被调用时,拦截器会尝试获取名为"myLock"的分布式锁,确保同一时间只有一个线程可以执行该方法。拦截器在方法执行前尝试获取分布式锁,如果成功获取到锁,则执行方法体;属性,用于指定锁的过期时间,默认为30秒。

UoEmacs_Lisp的博客 193

Redisson的配置

【代码】Redisson的配置。

qq_44861126的博客 6029

SpringBoot 中利用 Redisson 实现分布式锁

Redisson 是一款高级的分布式协调Redis客户端,其提供了一系列分布式数据结构和实用工具类,可以帮助开发人员快速、高效地处理分布式系统中的一些功能,比如缓存、分布式锁、分布式消息等。为了方便使用 Redisson 的功能,Spring Boot 在提供starter包的同时,也为我们提供了对 Redisson 的集成支持。本文将从 Spring Boot 中如何利用 Redisson 提供的分布式锁技术实现简单的分布式场景中的锁机制。

AI天才研究院 2918

SpringBoot--配置Redisson的方法

本文介绍如何在SpringBoot中配置Redisson。

IT利刃出鞘的博客 2万+

[springboot专栏]使用redisson实现分布式锁

Redisson是Redis官方推荐的Java版的Redis客户端(Jedis、letture也是官方推荐的java版本redis客户端程序)。它提供的功能非常多,也非常强大,特别是它默认提供的分布式锁支持功能。,包含多个子项目,对于我们本节比较有用的是集成redisson-spring-data-2x之后能够支持Spring Data redis及RedisTemplate。...

字母哥博客 2728

DDR5内存Training全解析:从信号完整性到CS训练模式的实战指南

本文深入解析了DDR5内存Training的全过程,从信号完整性挑战到CS训练模式(CSTM)的实战应用。文章详细阐述了Training在DDR5高频时代的关键作用,对比了In-Band与OOB两种架构,并拆解了Intel MRC的核心训练步骤,为硬件与固件工程师提供了诊断与优化系统稳定性的实用指南。

weixin_29252171的博客 1024

升级Redisson版本兼容问题

3.18.0 默认编码使用:MarshallingCodec,官方已经明确不再建议使用 FstCodec编码,并且移除了Fst相关依赖。版本: 3.10.6 默认使用了FstCodec 编码。

kevin_Luan的专栏 2571

window下迁移SVN仓库到新的windows服务器

window下迁移SVN仓库到新的windows服务器

Bertram的博客 4690

Spring Boot集成Redisson实现分布式锁

通过以上步骤,我们成功地在Spring Boot项目中集成了Redisson,并实现了分布式锁的功能。分布式锁可以保证多个节点对共享资源的安全访问,避免了并发访问带来的数据不一致和安全问题。在实际开发中,我们可以根据具体业务需求,使用分布式锁来保证数据的一致性和并发访问的安全性。

Java老兵的后端进阶与AI前沿探索之路。 2238

单细胞多组学数据整合分析实战:从原始数据到跨平台合并

本文详细介绍了单细胞多组学数据整合分析的实战流程,从原始数据处理到跨平台合并分析。通过Seurat和Harmony等工具的应用,帮助研究者有效解决批次效应问题,保留真实的生物学信号。文章包含代码示例和常见问题解决方案,特别适合需要进行单细胞合并分析的研究人员参考。

weixin_30752699的博客 89

3D数学-动力学

3D数学-11-动力学 旋转运动学 二维旋转动力学 首先我们考虑最简单的情况: 我们将F施加在圆盘(忽略质量)上的一个点(质量为m)上 图中:F为我们施加的力,O是枢轴原点。 通过基本的运算,我们可以得到 F'= F*sinθ 那么切向加速度 a = F'/ m 切向加速度是线性速度的加速度,我们通过除以半径获得角加速度 α = a / r 现在,我们换一种方式,那就是通过杠杆臂的方式去施加力 为了能够计算出m点的角加速度,我们需要引入一个概念:扭矩 他的理解类似于力矩,公式如下 τ = Flsi

韩天衣的博客 2285

阿里大牛详细讲解:Spring Boot 集成Redisson实现分布式锁

针对单机分布式锁还是存在锁定续期、可重入的问题,本文将采用Spring Boot 集成Ression实现分布式锁进行详细讲解。

欢迎来到我的博客 373

避坑指南:STM32CubeMX配置SDIO4bit模式时为什么卡在HAL_SD_ConfigWideBusOperation?

本文深入分析了使用STM32CubeMX配置SDIO 4位模式时,程序在HAL_SD_ConfigWideBusOperation函数处卡死的常见问题。文章从硬件连接、CubeMX配置、初始化序列及HAL库底层实现等多个维度剖析根源,并提供了从初始化流程优化到增强代码鲁棒性等实战解决方案,帮助开发者彻底解决这一棘手难题。

pca5navigator的博客 824

Spring Boot 集成 Redisson 实现分布式锁

文章目录1 摘要2 核心 Maven 依赖3 核心代码3.1 Redisson 配置类3.2 Redisson 配置文件(yml)3.3 使用示例4 验证锁是否生效5 推荐参考资料6 本次提交记录 ​ ​ 1 摘要 在分布式系统中高并发带来的除了流量大之外,更容易出现的是重复写操作的问题,典型的场景如抢票、购物等,一件商品只能卖一次,如果高并发的情况下,则容易出现一件商品被卖多次的情况。为避免重复写操作的问题,则需要通过加锁的方式保证写操作依次执行。常用的分布式锁实现方式有 Redis 和 Zookeepe

Mrqiang9001 989

快速上手:网页版EggNOG功能注释全流程解析

本文详细解析了网页版EggNOG在蛋白序列功能注释中的全流程操作,从初识工具到实战技巧,涵盖FASTA格式处理、参数设置、结果解读及常见问题解决方案。特别适合生物信息学初学者快速掌握这一高效注释工具,提升非模式生物基因组研究的注释效率。

weixin_29310631的博客 189

PLC与变频器联动控制:从开关量、模拟量到通讯的接线与编程实战

在工业自动化系统中,电机调速控制是核心需求之一,其关键在于实现可编程逻辑控制器(PLC)与变频器之间的可靠联动。其基本原理是通过PLC输出控制信号,由变频器接收并驱动电机按设定速度运行。这项技术的核心价值在于实现电机的软启停、精确调速与节能控制,广泛应用于风机、水泵、传送带及精密张力控制等场景。其中,开关量控制以其接线简单、抗干扰能力强的特点,成为基础且可靠的方案;而模拟量控制则能实现无级平滑调速,满足更高精度的工艺要求。本文以西门子、三菱等主流品牌为例,深入解析了这两种主流控制方式的硬件接线、参数设置与梯

1268

阿里大牛详细讲解:Spring Boot 集成 Redisson 实现分布式锁

本文针对 Spring Boot 集成 Redisson 的基本使用,关于 Redisson 源码的分析将在后续的文章中进行讲解,如有疑问,请随时反馈。

m0_69804655的博客 616

如何在Dify中安装运行pandas、numpy库(离线、在线均支持,可提供远程指导)

pandas和numpy这两个库是数据科学和数据分析中经常使用的工具包,原生的Dify无法直接使用这两个库,需要手动安装后才可以使用。本文将介绍如何在Dify中安装pandas和numpy,并在代码执行节点中运行使用pandas和numpy。Dify的代码执行节点中的python逻辑,实际是运行在Dify沙盒中的,因此我们在沙盒中安装pandas和numpy就可以了。如果您有在Dify中添加pandas、numpy的应用需求,欢迎关注作者进行交流。

litlit023的专栏 5632

基于 Redis 的分布式锁 Spring Boot 集成 Redisson 使用分布式锁确保对共享资源的互斥访问

工作中开发过一个上传文件的接口,每个区县都有自己的资源压缩包需要上传到系统,系统接收到压缩包后,需要解压,提取出里面的文件保存到文件服务器中,解析里面的SQLITE文件得到数据保存到数据库中。由于处理的过程会比较耗时,所以使用了异步处理的方式来优化用户体验,接口接收到文件后快速响应,返回上传成功,异步线程在后台继续执行解析压缩包业务逻辑。为了防止在异步线程处理期间,用户再次上传压缩包,从而导致上传资源数据不一致问题,在异步线程处理期间要获取锁来保证上传资源数据一致。

1345

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Spring Boot 3.x + Redis 7.x,轻松掌握Redisson分布式锁实战技巧,超详细教程

大家好,我是袁庭新。Redisson是一个基于Redis的Java驻内存数据网格(In-Memory Data Grid),它不仅提供了对Redis的全面支持,还实现了许多高级功能和服务。通过将Redis与Java实用工具包中常用接口相结合,Redisson为开发者提供了一系列具有分布式特性的工具类和对象。这使得原本用于协调单机多线程并发程序的工具获得了在分布式环境中协调多机多线程并发系统的能力。

2301_82300081的博客 1279

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

springboot集成redisson实现redis分布式锁

Redisson是Redis官方推荐的Java版的Redis客户端。它提供的功能非常多,也非常强大,此处我们只用它的分布式锁功能。 1、引入依赖 2、添加工具类RedisLock.java 3、新增配

hehehaha2025的博客 65

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Redisson(分布式锁、限流)

Redisson(分布式锁、限流)

weixin_42415173的博客 1430

Redis 作为分布式锁(一):SpringBoot集成Redisson分布式锁

文章目录一、项目Demo1.1 项目依赖1.2 项目配置-redis1.3 Redisson的配置类RedissonConfig1.4 定义一个Loker接口,用于分布式锁的一些操作1.5 基于Redisson的实现类RedissonLocker1.6 定义一个分布式锁工具类LockUtil1.7 单元测试1.8 源码二、Redisson 之 Redlock2.1 基于Redis命令的分布式锁2....

风尘博客 1445

springboot redisson分布式锁

1.添加依赖 <!--springboot startWeb --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version&gt

qq_38886614的博客 287

SpringBoot集成redisson

1.首先需要已经集成redis的环境,如何集成redis这里不做描述。 2.引入redisson的依赖。(这里使用的是3.14.1版本) <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.14.1</version> </dependency>

感谢关注点赞,笔芯啾咪! 8407

Redisson(分布式锁)+springBoot集成的几种方式

文章目录前言1.Redisson 简介2.集成方式2.1 自定义配置属性+手动注入2.2 使用Yaml()方式批量读取配置2.3 使用SpringBoot自动配置类3. 工具类4. 总结 前言 1.Redisson 简介 2.集成方式 2.1 自定义配置属性+手动注入 2.2 使用Yaml()方式批量读取配置 2.3 使用SpringBoot自动配置类 3. 工具类 4. 总结 ...

米二的博客 1653
上一篇: 18个MyBatis高频知识及学习笔记,啃完面试不愁!
下一篇: spring接口多实现类,该依赖注入哪一个?
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值