SpringBoot集成redisson分布式锁
官方文档: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:,10.47.91.83:,10.47.91.83:
更多的配置信息可以去官网查看
SpringBoot集成redisson分布式锁的更多相关文章
- [转帖]SpringBoot集成redisson分布式锁
		
SpringBoot集成redisson分布式锁 https://www.cnblogs.com/yangzhilong/p/7605807.html 前几天同事刚让增加上这一块东西. 百度查一下 啥 ...
 - 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)是如何实现的? 加锁成功 在前一篇文章中介绍了可重入锁加锁的 ...
 
随机推荐
- 基于Vue、Bootstrap的Tab形式的进度展示
			
最近基于Vue.Bootstrap做了一个箭头样式的进度展示的单页应用,并且支持了对于一个本地JS文件的检索,通过这个单页应用,对于Vue的理解又深入了一些.在这里把主要的代码分享出来. 本单页应用实 ...
 - 零基础写python爬虫之使用Scrapy框架编写爬虫
			
网络爬虫,是在网上进行数据抓取的程序,使用它能够抓取特定网页的HTML数据.虽然我们利用一些库开发一个爬虫程序,但是使用框架可以大大提高效率,缩短开发时间.Scrapy是一个使用Python编写的,轻 ...
 - [转]HIVE UDF/UDAF/UDTF的Map Reduce代码框架模板
			
FROM : http://hugh-wangp.iteye.com/blog/1472371 自己写代码时候的利用到的模板 UDF步骤: 1.必须继承org.apache.hadoop.hive ...
 - 使用Bootstrap后,关于IE与Chrome显示字体的问题
			
在做日志系统时,使用了Bootstrap,然后通过浏览器查看的页面效果如下 对比可以看到,同样的字体,IE显示的圆润些,而Chrome字体则丑很多.因为Chrome默认用宋体 在http://v3.b ...
 - 访问Oracle数据库的工具【unfinished】
			
ylbtech-Oracle:访问Oracle数据库的工具 访问Oracle数据库的工具 1. SQL*PLUS返回顶部 1.0, 1.0.1, 之network\admin\tnsnames.ora ...
 - 数学图形之贝塞尔(Bézier)曲面
			
前面章节中讲了贝塞尔(Bézier)曲线,而贝塞尔曲面是对其多一个维度的扩展.其公式依然是曲线的公式: . 而之所以由曲线变成曲面,是将顶点横向连了再纵向连. 很多计算机图形学的教程都会有贝塞尔曲面的 ...
 - FMX.Controls单元 中图形矩阵变换
			
procedure TControl.DoMatrixChanged(Sender: TObject);var TranslateMatrix, ScaleMatrix, RotMatrix: TMa ...
 - IIS通过HTML5实现应用程序缓存的离线浏览
			
这里我是使用的IIS7: IIS7发布了网站后要想使用HTML5的应用程序缓存,需要增加一个关于文本/缓存清单( text/cache-manifest)的新的MIME类型,选中网站添加一个MIME类 ...
 - 操作系统重点双语阅读 - 上下文切换 Context Switch
			
The context is represented in the PCB of the process. It includes the value of the CPU registers, th ...
 - Tensorflow中张量数据类型的转换
			
https://blog.csdn.net/Tramac/article/details/74942587 字符串转为数字: tf.string_to_number (string_tensor, o ...