SpringBoot3.4.0整合Redisson实现分布式锁
SpringBoot3.4.0整合Redisson实现分布式锁

今天我们基于SpringBoot3整合Redis客户端开源组件Redisson,我们在开发项目的时候分布式缓存是一个基础的中间件,会被经常使用到。可以使用缓存提升我们系统的性能,可以使用Redis的发布订阅机制实现轻量级的消息发送功能。也可以使用缓存存储我们系统中的热点数据,接下来我们先看今天的主题基于Redisson实现分布式锁。
1 Redisson分布式锁优势
使用 Redisson 实现分布式锁相对于自己直接基于Redis 实现分布式锁,在功能完善性、开发便利性以及可扩展性方面具有显著的优势。以下是 Redisson 实现分布式锁相对于自己基于 Redis 实现分布式锁的几个主要优势:
优势 | Redisson 实现分布式锁 | 基于 Redis 实现分布式锁 |
---|---|---|
锁机制 | 可重入锁、公平锁、读写锁等丰富的锁机制 | 需要写代码实现 |
锁续期 | 自动续期,防止锁超时失效 | 需要写代码实现续期 |
操作原子性 | 内置保证 | 需要写代码保障原子性 |
易用性 | API 简单,易于使用和维护 | 需要写代码实现命令逻辑 |
部署架构 | 支持单点、哨兵、集群模式 | 需要写代码实现高可用 |
高级功能 | 异步、分布式对象、反压支持 | 需要自己封装代码 |
异步和同步 | 完善的异步和反应式支持 | 需要编写异步代码 |
通过 Spring Boot 3.4.0 和 Redisson 的整合,可以轻松实现分布式锁的功能,确保在分布式系统中需要保证线程安全的关键业务正确执行。Redisson 提供了多种锁的实现,如公平锁、读写锁、可重入锁等,可以满足不同的业务需求。
完整代码在文章最后,如果觉得本篇文章对你有用,记得点赞、关注、收藏哦。你的支持是我持续更新的动力!
SpringBoot3专栏软件环境
- JDK17.0.12
- SpringBoot3.4.0
- redisson-spring-boot-starter3.38.1
- contiperf2.3.4
- IDEA2024.2.0.2
我们先看本篇文章对应的项目结构,请看下图

2 项目搭建
2.1 父工程依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itbeien</groupId>
<artifactId>springboot3-labs-master</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.0</version>
</parent>-->
<modules>
<module>springboot-nacos</module>
<module>springboot-mybatis-plus</module>
<module>spingboot-mybatis</module>
<module>mybatis-generator</module>
<module>springboot-mybatis-nacos</module>
<module>dynamic-datasource-mybatis-plus</module>
<module>springboot-mapstruct</module>
<module>springboot-mapstruct-lombok</module>
<module>springboot-rocketmq</module>
<module>springboot-redisson</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<nacos-config-spring-boot-starter-version>0.2.12</nacos-config-spring-boot-starter-version>
<lombok-version>1.18.34</lombok-version>
<mybatis-plus-spring-boot3-starter-version>3.5.9</mybatis-plus-spring-boot3-starter-version>
<mysql-connector-java-version>5.1.49</mysql-connector-java-version>
<spring-boot-dependencies-version>3.4.0</spring-boot-dependencies-version>
<mybatis-spring-boot-version>3.0.3</mybatis-spring-boot-version>
<mapstruct-verrsion>1.5.5.Final</mapstruct-verrsion>
<mapstruct-processor-version>1.5.5.Final</mapstruct-processor-version>
<rocketmq-spring-boot-starter-version>2.3.1</rocketmq-spring-boot-starter-version>
<fastjson-vesion>2.0.53</fastjson-vesion>
<redisson-spring-boot-starter-version>3.38.1</redisson-spring-boot-starter-version>
<contiperf-version>2.3.4</contiperf-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-dependencies-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${nacos-config-spring-boot-starter-version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok-version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus-spring-boot3-starter-version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java-version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct-verrsion}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct-processor-version}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq-spring-boot-starter-version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson-vesion}</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson-spring-boot-starter-version}</version>
</dependency>
<dependency>
<groupId>org.databene</groupId>
<artifactId>contiperf</artifactId>
<version>${contiperf-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2.2 Redisson项目依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.itbeien</groupId>
<artifactId>springboot3-labs-master</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>springboot-redisson</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit-version>4.13.2</junit-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.databene</groupId>
<artifactId>contiperf</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
</dependency>
</dependencies>
</project>
2.3 项目配置信息
# 在 application.yml 文件中,配置 Redis 的连接信息,该配置以单机版 Redis 为例。config: 后面跟着一个管道符 (|),表示一个多行字符串,也就是一个整体
server:
port: 1002
spring:
redis:
redisson:
config: |
singleServerConfig:
address: redis://192.168.0.104:6379 # Redis 连接地址,前缀为 redis://
password: Rootpwd20240809 # 如果 Redis 需要密码认证,则填写密码
timeout: 3000 # 命令执行超时时间(毫秒)
#spring:
# redis:
# redisson:
# config: |
# clusterServersConfig:
# password:
# nodeAddresses:
# - redis://192.168.0.111:6379
# - redis://192.168.0.115:6379
# - redis://192.168.0.116:6379
2.4 代码实现
2.4.1 配置信息
package cn.itbeien.redisson.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2024 itbeien
*/
@ConfigurationProperties(prefix = "spring.redis.redisson")
@Data
@Component
public class RedissonProperties {
private String config;
private String file;
}
package cn.itbeien.redisson.config;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2024 itbeien
*/
@Configuration
@Slf4j
public class RedissonConfig {
@Autowired
private RedissonProperties redissonProperties;
@Bean
public RedissonClient redissonClient() throws Exception{
Config config = Config.fromYAML(redissonProperties.getConfig());
Redisson.create(config);
log.info("Redisson 已启动");
return Redisson.create(config);
}
}
2.4.2 分布式锁实现
package cn.itbeien.redisson.service;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2024 itbeien
*/
@Service
@Slf4j
public class LockService {
private final RedissonClient redissonClient;
public LockService(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}
public void doLock() {
/***
* 获取锁对象
* RLock:这是 Redisson 提供的分布式锁对象。通过 RedissonClient.getLock() 方法可以获取到一个分布式锁。
*/
RLock lock = redissonClient.getLock("itbeienLock");
try {
/**
* tryLock(long waitTime, long leaseTime, TimeUnit unit):此方法尝试获取锁,其中:
* waitTime 是最大等待时间,表示在该时间内如果未获取到锁则放弃。
* leaseTime 是锁的自动释放时间,避免因为业务逻辑异常导致锁无法释放。
* 尝试获取锁,等待时间 100ms,锁定时间 8秒
*/
if (lock.tryLock(100, 8, TimeUnit.SECONDS)) {
try {
// 加锁成功,执行业务逻辑
log.info("锁定成功,执行业务逻辑...");
Thread.sleep(5000); // 模拟执行业务逻辑
} finally {
/**
* 释放锁
* unlock():业务逻辑执行完后需要手动释放锁,否则其他线程将无法获取锁
*/
lock.unlock();
log.info("业务逻辑已经执行完毕,已释放锁");
}
} else {
log.info("无法获取锁,其他线程正在执行该任务");
}
} catch (InterruptedException e) {
log.error("获取分布式锁异常:{}",e.getMessage());
}
}
}
3 分布式锁代码测试
package cn.itbeien.redisson.test;
import cn.itbeien.redisson.service.LockService;
import org.databene.contiperf.PerfTest;
import org.databene.contiperf.junit.ContiPerfRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2024 itbeien
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedissonApplication {
@Autowired
private LockService lockService;
/**
* 进行性能测试
*/
@Rule
public ContiPerfRule contiPerfRule = new ContiPerfRule();
/**
* threads:线程池数量n,并发执行n个线程;
* invocations:执行次数n,与线程数量无关,默认值为1;
* duration:重复执行时间n,测试至少执行n毫秒;
* 同时添加invocations和duration时,执行二者中测试数多的。
* 并发执行测试分布式锁是否生效
*/
@Test
@PerfTest(invocations = 5,threads = 5)
public void test(){
lockService.doLock();
}
}
4 测试结果

欢迎大家关注我的项目实战内容itbeien.cn,一起学习一起进步,在项目和业务中理解各种技术。

欢迎沟通交流技术和支付业务,一起探讨聚合支付/预付卡系统业务、技术、系统架构、微服务、容器化。并结合聚合支付系统深入技术框架/微服务原理及分布式事务原理。加入我的知识星球吧

SpringBoot3专栏
01SpringBoot3专栏-SpringBoot3.4.0整合Mybatis-plus和Mybatis
02SpringBoot3.4.0结合Mybatis-plus实现动态数据源
03mapstruct对象映射在Springboot3中这样用就对了
04RocketMQ5.3.1集成SpringBoot3.4.0就这样简单
跟着我学微服务系列
01跟着我学微服务,什么是微服务?微服务有哪些主流解决方案?
05SpringCloudAlibaba之图文搞懂微服务核心组件在企业级支付系统中的应用
06JDK17+SpringBoot3.4.0+Netty4.1.115搭建企业级支付系统POS网关
07JDK17+SpringCloud2023.0.3搭建企业级支付系统-预付卡支付交易微服务
08JDK17+Dubbo3.3.2搭建企业级支付系统-预付卡支付交易微服务
09JDK17+SpringBoot3.3.6+Netty4.1.115实现企业级支付系统POS网关签到功能
贝恩聊架构-项目实战地址
5 源码地址
贝恩聊架构-SpringBoot3专栏系列文章、资料和源代码会同步到以下地址,代码和资料每周都会同步更新
该仓库地址主要用于贝恩聊架构-SpringBoot3专栏、基于企业级支付系统,学习微服务整体技术栈
