[转帖]SpringBoot集成redisson分布式锁
SpringBoot集成redisson分布式锁
https://www.cnblogs.com/yangzhilong/p/7605807.html 前几天同事刚让增加上这一块东西. 百度查一下 啥意思.. 学习一下.
官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95
20180226更新:增加tryLock方法,建议后面去掉DistributedLocker接口和其实现类,直接在RedissLockUtil中注入RedissonClient实现类(简单但会丢失接口带来的灵活性)。
20190711更新:redisson官方发布了redisson-spring-boot-starter,具体可以参考:https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter#spring-boot-starter
1、引用redisson的pom
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.5.0</version> </dependency>
2、定义Lock的接口定义类

import java.util.concurrent.TimeUnit; import org.redisson.api.RLock; public interface DistributedLocker { RLock lock(String lockKey); RLock lock(String lockKey, int timeout); RLock lock(String lockKey, TimeUnit unit, int timeout); boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime); void unlock(String lockKey); void unlock(RLock lock); }

3、Lock接口实现类

import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import java.util.concurrent.TimeUnit; public class RedissonDistributedLocker implements DistributedLocker { private RedissonClient redissonClient; @Override public RLock lock(String lockKey) { RLock lock = redissonClient.getLock(lockKey); lock.lock(); return lock; } @Override public RLock lock(String lockKey, int leaseTime) { RLock lock = redissonClient.getLock(lockKey); lock.lock(leaseTime, TimeUnit.SECONDS); return lock; } @Override public RLock lock(String lockKey, TimeUnit unit ,int timeout) { RLock lock = redissonClient.getLock(lockKey); lock.lock(timeout, unit); return lock; } @Override 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; } } @Override public void unlock(String lockKey) { RLock lock = redissonClient.getLock(lockKey); lock.unlock(); } @Override public void unlock(RLock lock) { lock.unlock(); } public void setRedissonClient(RedissonClient redissonClient) { this.redissonClient = redissonClient; } }

4、redisson属性装配类

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "redisson") @ConditionalOnProperty("redisson.password") public class RedissonProperties { private int timeout = 3000; private String address; private String password; private int database = 0; private int connectionPoolSize = 64; private int connectionMinimumIdleSize=10; private int slaveConnectionPoolSize = 250; private int masterConnectionPoolSize = 250; private String[] sentinelAddresses; private String masterName; public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public int getSlaveConnectionPoolSize() { return slaveConnectionPoolSize; } public void setSlaveConnectionPoolSize(int slaveConnectionPoolSize) { this.slaveConnectionPoolSize = slaveConnectionPoolSize; } public int getMasterConnectionPoolSize() { return masterConnectionPoolSize; } public void setMasterConnectionPoolSize(int masterConnectionPoolSize) { this.masterConnectionPoolSize = masterConnectionPoolSize; } public String[] getSentinelAddresses() { return sentinelAddresses; } public void setSentinelAddresses(String sentinelAddresses) { this.sentinelAddresses = sentinelAddresses.split(","); } public String getMasterName() { return masterName; } public void setMasterName(String masterName) { this.masterName = masterName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getConnectionPoolSize() { return connectionPoolSize; } public void setConnectionPoolSize(int connectionPoolSize) { this.connectionPoolSize = connectionPoolSize; } public int getConnectionMinimumIdleSize() { return connectionMinimumIdleSize; } public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) { this.connectionMinimumIdleSize = connectionMinimumIdleSize; } public int getDatabase() { return database; } public void setDatabase(int database) { this.database = database; } public void setSentinelAddresses(String[] sentinelAddresses) { this.sentinelAddresses = sentinelAddresses; } }

5、SpringBoot自动装配类

import org.apache.commons.lang3.StringUtils; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.config.SentinelServersConfig; import org.redisson.config.SingleServerConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.longge.lock.DistributedLocker; import com.longge.lock.RedissonDistributedLocker; import com.longge.lock.RedissonProperties; import com.longge.utils.RedissLockUtil; @Configuration @ConditionalOnClass(Config.class) @EnableConfigurationProperties(RedissonProperties.class) public class RedissonAutoConfiguration { @Autowired private RedissonProperties redssionProperties; /** * 哨兵模式自动装配 * @return */ @Bean @ConditionalOnProperty(name="redisson.master-name") RedissonClient redissonSentinel() { Config config = new Config(); SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redssionProperties.getSentinelAddresses()) .setMasterName(redssionProperties.getMasterName()) .setTimeout(redssionProperties.getTimeout()) .setMasterConnectionPoolSize(redssionProperties.getMasterConnectionPoolSize()) .setSlaveConnectionPoolSize(redssionProperties.getSlaveConnectionPoolSize()); if(StringUtils.isNotBlank(redssionProperties.getPassword())) { serverConfig.setPassword(redssionProperties.getPassword()); } return Redisson.create(config); } /** * 单机模式自动装配 * @return */ @Bean @ConditionalOnProperty(name="redisson.address") RedissonClient redissonSingle() { Config config = new Config(); SingleServerConfig serverConfig = config.useSingleServer() .setAddress(redssionProperties.getAddress()) .setTimeout(redssionProperties.getTimeout()) .setConnectionPoolSize(redssionProperties.getConnectionPoolSize()) .setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize()); if(StringUtils.isNotBlank(redssionProperties.getPassword())) { serverConfig.setPassword(redssionProperties.getPassword()); } return Redisson.create(config); } /** * 装配locker类,并将实例注入到RedissLockUtil中 * @return */ @Bean DistributedLocker distributedLocker(RedissonClient redissonClient) { DistributedLocker locker = new RedissonDistributedLocker(); locker.setRedissonClient(redissonClient); RedissLockUtil.setLocker(locker); return locker; } }

6、Lock帮助类

import java.util.concurrent.TimeUnit; import org.redisson.api.RLock; import DistributedLocker; /** * redis分布式锁帮助类 * @author yangzhilong * */ public class RedissLockUtil { private static DistributedLocker redissLock; public static void setLocker(DistributedLocker locker) { redissLock = locker; } /** * 加锁 * @param lockKey * @return */ public static RLock lock(String lockKey) { return redissLock.lock(lockKey); } /** * 释放锁 * @param lockKey */ public static void unlock(String lockKey) { redissLock.unlock(lockKey); } /** * 释放锁 * @param lock */ public static void unlock(RLock lock) { redissLock.unlock(lock); } /** * 带超时的锁 * @param lockKey * @param timeout 超时时间 单位:秒 */ public static RLock lock(String lockKey, int timeout) { return redissLock.lock(lockKey, timeout); } /** * 带超时的锁 * @param lockKey * @param unit 时间单位 * @param timeout 超时时间 */ public static RLock lock(String lockKey, TimeUnit unit ,int timeout) { return redissLock.lock(lockKey, unit, timeout); } /** * 尝试获取锁 * @param lockKey * @param waitTime 最多等待时间 * @param leaseTime 上锁后自动释放锁时间 * @return */ public static boolean tryLock(String lockKey, int waitTime, int leaseTime) { return redissLock.tryLock(lockKey, TimeUnit.SECONDS, waitTime, leaseTime); } /** * 尝试获取锁 * @param lockKey * @param unit 时间单位 * @param waitTime 最多等待时间 * @param leaseTime 上锁后自动释放锁时间 * @return */ public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) { return redissLock.tryLock(lockKey, unit, waitTime, leaseTime); } }

属性文件实例:
1、单机模式
# redisson lock redisson.address=redis://10.18.75.115:6379 redisson.password=
这里如果不加redis://前缀会报URI构建错误,
Caused by: java.net.URISyntaxException: Illegal character in scheme name at index 0
其次,在redis进行连接的时候如果不对密码进行空判断,会出现AUTH校验失败的情况。
Caused by: org.redisson.client.RedisException: ERR Client sent AUTH, but no password is set. channel
2、哨兵模式
redisson.master-name=mymaster redisson.password=xxxx redisson.sentinel-addresses=10.47.91.83:26379,10.47.91.83:26380,10.47.91.83:26381
更多的配置信息可以去官网查看
[转帖]SpringBoot集成redisson分布式锁的更多相关文章
- SpringBoot集成redisson分布式锁
官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95 20180226更新:增加tryLock方法,建议后面去掉Distr ...
- springboot整合redisson分布式锁
一.通过maven引入redisson的jar包 <dependency> <groupId>org.redisson</groupId> <artifact ...
- SpringBoot集成Redis分布式锁以及Redis缓存
https://blog.csdn.net/qq_26525215/article/details/79182687 集成Redis 首先在pom.xml中加入需要的redis依赖和缓存依赖 < ...
- Redisson分布式锁的简单使用
一:前言 我在实际环境中遇到了这样一种问题,分布式生成id的问题!因为业务逻辑的问题,我有个生成id的方法,是根据业务标识+id当做唯一的值! 而uuid是递增生成的,从1开始一直递增,那么在同一台机 ...
- Redisson分布式锁实现
转: Redisson分布式锁实现 2018年09月07日 15:30:32 校长我错了 阅读数:3303 转:分布式锁和Redisson实现 概述 分布式系统有一个著名的理论CAP,指在一个分布 ...
- Redisson 分布式锁实战与 watch dog 机制解读
Redisson 分布式锁实战与 watch dog 机制解读 目录 Redisson 分布式锁实战与 watch dog 机制解读 背景 普通的 Redis 分布式锁的缺陷 Redisson 提供的 ...
- 又长又细,万字长文带你解读Redisson分布式锁的源码
前言 上一篇文章写了Redis分布式锁的原理和缺陷,觉得有些不过瘾,只是简单的介绍了下Redisson这个框架,具体的原理什么的还没说过呢.趁年前项目忙的差不多了,反正闲着也是闲着,不如把Rediss ...
- Redisson 分布式锁实现之前置篇 → Redis 的发布/订阅 与 Lua
开心一刻 我找了个女朋友,挺丑的那一种,她也知道自己丑,平常都不好意思和我一块出门 昨晚,我带她逛超市,听到有两个人在我们背后小声嘀咕:"看咱前面,想不到这么丑都有人要." 女朋友 ...
- Redisson 分布式锁源码 02:看门狗
前言 说起 Redisson,比较耳熟能详的就是这个看门狗(Watchdog)机制. 本文就一起看看加锁成功之后的看门狗(Watchdog)是如何实现的? 加锁成功 在前一篇文章中介绍了可重入锁加锁的 ...
随机推荐
- sort()函数中的key
d = { , , } #for k in d.items(): # print(k) content = list(d.items()) print(content) content.sort(ke ...
- Codechef:Fibonacci Number/FN——求通项+二次剩余+bsgs
题意 定义 $F_n$ 为 $$F_n = \left\{\begin{matrix}0, n=0\\ 1, n=1 \\F_{n-1} + F_{n-2}, n > 1\end{matrix} ...
- docker拷贝宿主与容器中的文件
从容器里面拷文件到宿主机 语法:docker cp 容器名:要拷贝的文件在容器里面的路径 要拷贝到宿主机的相应路径 例子:容器名为ubuntu,要从容器里面拷贝的文件路为:/usr/local/tom ...
- Android学习小结
自从学习Android以来已经经过三个月了,如今市场对于Android工程师的需求接近饱和,所以学习Android的人也少了很多,很多的培训机构也逐渐将Android课程淘汰,导致学习Android的 ...
- 持续集成学习1 gitlab和jenkins安装
一.gitlab安装参照链接 https://www.cnblogs.com/linuxk/p/10100431.html 二.安装jenkins 1.获取jenkins源码包 https://blo ...
- vue 首页导航+左侧菜单
1. Mock.js 前后端分离开发开发过程当中,经常会遇到以下几个尴尬的场景: 1. 老大,接口文档还没输出,我的好多活干不下去啊! 2. 后端小哥,接口写好了没,我要测试啊! 前后端分离之后,前端 ...
- WinDbg常用命令系列---.effmach
.effmach (Effective Machine) .effmach命令显示或更改调试器使用的处理器模式. .effmach [MachineType] 参数: MachineType指定调试器 ...
- 深度讨论i++问题
例题1:下列程序的输出结果是多少? public class Test { static { int x = 5; } static int x, y; public static void main ...
- QHUOJ - 1533: 计算组合数(大数计算)
题目描述 给定两个正整数n,m,计算组合数C(n,m).组合数计算公式为:C(n,m)=n!/((n-m)!*m!) 已知n,m <= 50. 结果很大需要使用long long存储. 输入 输 ...
- 刷题记录:[0CTF 2016]piapiapia
目录 刷题记录:[0CTF 2016]piapiapia 一.涉及知识点 1.数组绕过正则及相关 2.改变序列化字符串长度导致反序列化漏洞 二.解题方法 刷题记录:[0CTF 2016]piapiap ...