首先,不要将分布式锁想的太复杂,如果我们只是平时业务中去使用,其实不算难,但是很多人写的文章不能让人快速上手,接下来,一起看下Redisson分布式锁的快速实现
Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格客户端(In-Memory Data Grid)。它不仅提供了一系列的 redis 常用数据结构命令服务,还提供了许多分布式服务,例如分布式锁、分布式对象、分布式集合、分布式远程服务、分布式调度任务服务等等。
Redisson:其实就是相当于在redis的基础上进行了加强,让redisson不像redis的分布式是直接基于指令setnx(set if not exists: 如果不存在)去实现的。
因为redission是基于redis的,所以我们需要本地安装reids,redis安装这里就不演示了,这里是使用springboot创建的项目,我们默认项目已经创建完成了,所以直接开始配置
项目结构
#以下是application.yml中的配置
server:
port: 8083
spring:
redis:
host: localhost
port: 6379
timeout: 1000
jedis:
pool:
min-idle: 5
max-idle: 10
max-wait: -1
org.springframework.boot
spring-boot-starter-data-redis
org.redisson
redisson
3.17.7
package cn.sendmsg.test;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
@Slf4j
public class redissonController {
@RequestMapping("/testLock")
public void testRedissLock(){
// 使用Redisson 设置分布式锁
//1、配置Redisson客户端 Config对象用于配置 Redisson 客户端的参数。
Config config = new Config();
//2、连接地址 连接方式redis:// 或者 rediss://
// 集群使用
// config.useClusterServers()
// .setScanInterval(2000) // 集群状态扫描间隔时间,单位是毫秒
// //可以用"rediss://"来启用SSL连接
// .addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001")
// .addNodeAddress("redis://127.0.0.1:7002");
/*
* userSingleServer():指定使用单个redis服务配置
* setAddress() : 设置 Redis 服务器的地址
* setPassWord(): 设置连接 Redis 服务器的密码,如果有的话
* setDatabase(0): 设置连接的数据库索引,0就表示第一个
* */
config.useSingleServer().setAddress("redis://localhost:6379");
//3、 创建Redisson客户端
RedissonClient redissonClient = Redisson.create(config);
String lockValue = "isLock";
// 获取红锁
RLock redissonLock = redissonClient.getLock(lockValue);
try {
// 后去锁,如果获取到返回true
// tryLock():尝试3秒内获取锁,如果获取到了,最长3秒自动释放
boolean lock = redissonLock.tryLock(3L,3L, TimeUnit.SECONDS);
// 获取锁后,开始执行需要加锁的逻辑代码
if(lock){
System.out.println("获取到锁了");
for(int i =0;i<5;i++){
log.info("执行逻辑,查看打印结果:{}",i);
}
}
} catch (InterruptedException e) {
log.info("获取锁失败,失败原因:{}",e.getMessage());
throw new RuntimeException(e);
}finally {
// 最后一定要释放锁,不然有可能造成死锁现象
redissonLock.unlock();
}
}
// 用于jmater测试不加锁的信息,对比看
@RequestMapping("/testNoLock")
public void testRedissNoLock(){
for(int i =0;i< 10;i++){
log.info("无分布式锁的逻辑:"+i);
}
}
}
以下是jmater工具页面截图,这个花3分钟时间,自己学习下,主要还是设置yml、pom.xml、测试类,这个属于工具
获取到锁了
2023-11-14 14:51:45.840 INFO 40508 --- [nio-8083-exec-4] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:0
2023-11-14 14:51:45.840 INFO 40508 --- [nio-8083-exec-4] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:1
2023-11-14 14:51:45.840 INFO 40508 --- [nio-8083-exec-4] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:2
2023-11-14 14:51:45.840 INFO 40508 --- [nio-8083-exec-4] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:3
2023-11-14 14:51:45.840 INFO 40508 --- [nio-8083-exec-4] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:4
获取到锁了
2023-11-14 14:51:45.862 INFO 40508 --- [nio-8083-exec-5] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:0
2023-11-14 14:51:45.862 INFO 40508 --- [nio-8083-exec-5] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:1
2023-11-14 14:51:45.862 INFO 40508 --- [nio-8083-exec-5] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:2
2023-11-14 14:51:45.862 INFO 40508 --- [nio-8083-exec-5] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:3
2023-11-14 14:51:45.862 INFO 40508 --- [nio-8083-exec-5] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:4
获取到锁了
2023-11-14 14:51:45.866 INFO 40508 --- [nio-8083-exec-2] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:0
2023-11-14 14:51:45.866 INFO 40508 --- [nio-8083-exec-2] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:1
2023-11-14 14:51:45.866 INFO 40508 --- [nio-8083-exec-2] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:2
2023-11-14 14:51:45.866 INFO 40508 --- [nio-8083-exec-2] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:3
2023-11-14 14:51:45.866 INFO 40508 --- [nio-8083-exec-2] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:4
获取到锁了
2023-11-14 14:51:45.869 INFO 40508 --- [nio-8083-exec-3] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:0
2023-11-14 14:51:45.869 INFO 40508 --- [nio-8083-exec-3] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:1
2023-11-14 14:51:45.869 INFO 40508 --- [nio-8083-exec-3] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:2
2023-11-14 14:51:45.869 INFO 40508 --- [nio-8083-exec-3] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:3
2023-11-14 14:51:45.869 INFO 40508 --- [nio-8083-exec-3] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:4
获取到锁了
2023-11-14 14:51:45.872 INFO 40508 --- [nio-8083-exec-1] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:0
2023-11-14 14:51:45.872 INFO 40508 --- [nio-8083-exec-1] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:1
2023-11-14 14:51:45.872 INFO 40508 --- [nio-8083-exec-1] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:2
2023-11-14 14:51:45.872 INFO 40508 --- [nio-8083-exec-1] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:3
2023-11-14 14:51:45.872 INFO 40508 --- [nio-8083-exec-1] cn.sendmsg.test.redissonController : 执行逻辑,查看打印结果:4
到这里,其实我们就已经实现Redisson分布式锁了,不要把这个想的太复杂,可能在集群时需要注意些。 示例代码中演示了集群时如何设置。这是一个简单的案例,但实际开发者,获取锁-释放锁也是这么用的。加油
不加锁,for循环打印时,输出日志就不是有顺序的
15:00:40.217 INFO 40508 --- [io-8083-exec-17] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:3
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-17] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:4
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-17] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:5
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-17] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:6
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-17] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:7
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-17] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:8
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-17] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:9
2023-11-14 15:00:40.081 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:1
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:2
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:3
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:4
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:5
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:6
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:7
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:8
2023-11-14 15:00:40.217 INFO 40508 --- [io-8083-exec-16] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:9
2023-11-14 15:00:40.078 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:5
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:6
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:7
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:8
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:9
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:0
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:1
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:2
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:3
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:4
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:5
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:6
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:7
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:8
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-23] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:9
2023-11-14 15:00:40.210 INFO 40508 --- [io-8083-exec-25] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:6
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-25] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:7
2023-11-14 15:00:40.218 INFO 40508 --- [io-8083-exec-25] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:8
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:0
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:1
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:2
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:3
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:4
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:5
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:6
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:7
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:8
2023-11-14 15:00:40.218 INFO 40508 --- [nio-8083-exec-7] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:9
2023-11-14 15:00:40.211 INFO 40508 --- [io-8083-exec-26] cn.sendmsg.test.redissonController : 无分布式锁的逻辑:0