博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot集成redisson分布式锁
阅读量:4646 次
发布时间:2019-06-09

本文共 10096 字,大约阅读时间需要 33 分钟。

官方文档:

20180226更新:增加tryLock方法,建议后面去掉DistributedLocker接口和其实现类,直接在RedissLockUtil中注入RedissonClient实现类(简单但会丢失接口带来的灵活性)。

20190711更新:redisson官方发布了redisson-spring-boot-starter,具体可以参考:

 

1、引用redisson的pom

org.redisson
redisson
3.5.0

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 lockredisson.address=redis://10.18.75.115:6379redisson.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=mymasterredisson.password=xxxxredisson.sentinel-addresses=10.47.91.83:26379,10.47.91.83:26380,10.47.91.83:26381

更多的配置信息可以去官网查看

转载于:https://www.cnblogs.com/yangzhilong/p/7605807.html

你可能感兴趣的文章
正由另一进程使用,因此该进程无法访问此文件。
查看>>
1 线性空间
查看>>
VS不显示最近打开的项目
查看>>
MyEclipse安装Freemarker插件
查看>>
计算多项式的值
查看>>
DP(动态规划)
查看>>
chkconfig
查看>>
TMS320F28335项目开发记录2_CCS与JTAG仿真器连接问题汇总
查看>>
最强的篮球队和马尔可夫模型
查看>>
pyQt 每日一练习 -- 登录框
查看>>
wp 删除独立存储空间文件(多级非空文件夹删除)
查看>>
Loadrunner安装使用入门
查看>>
smartupload 上传文件时 把页面编码改成gbk 解决乱码
查看>>
EPS是什么格式
查看>>
Python的数据库操作(Sqlalchemy)
查看>>
2.抽取代码(BaseActivity)
查看>>
My simplified pickit2 clone
查看>>
Redis 入门知识
查看>>
夏天过去了, 姥爷推荐几套来自smashingmagzine的超棒秋天主题壁纸
查看>>
转--Android如何在java代码中设置margin
查看>>