springboot集成redisson
一、简介
Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。
Redisson在基于NIO的Netty框架上,充分的利用了Redis键值数据库提供的一系列优势,在Java实用工具包中常用接口的基础上,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。
redisson:
Redisson中客户端一旦加锁成功,就会启动一个watch dog看门狗。watch dog是一个后台线程,会每隔10秒检查一下,如果客户端还持有锁key,那么就会不断的延长锁key的生存时间。
默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。
redisson的lock不加超时时间默认启动看门狗,如果加了指定的超时时间则不启用看门狗
//启用看门狗
lock.lock();
//不启用看门狗
lock.lock(timeout,timeUnit);
二、依赖
redisson对应springboot的版本如下:
redisson-spring-boot-starter的3.26.1对应spring-boot的3.2.2;
redisson-spring-boot-starter的3.26.0对应spring-boot的3.2.0;
redisson-spring-boot-starter的3.18.0对应spring-boot的2.7.2;
redisson-spring-boot-starter的3.16.0对应spring-boot的2.4.4;
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.15.4</version>
</dependency>
三、配置文件
在resources目录下增加以下几个配置文件:
公共配置,最后下面选择要配置的配置文件如下:
spring:
redis:
redisson:
config: |
singleServerConfig:
3.1 单机配置
singleServerConfig:
#如果一段timeout时间未使用池化连接,并且当前连接量大于最小空闲连接池大小,则它将关闭并从池中删除。值(以毫秒为单位)。默认10000
idleConnectionTimeout: 10000
#连接到任何Redis服务器时超时。默认10000
connectTimeout: 10000
#Redis服务器响应超时。成功发送Redis命令后,开始倒数计时。值(以毫秒为单位)。默认3000
timeout: 3000
#超时重试次数,默认3次
retryAttempts: 3
#重试的时间间隔,默认1500毫秒
retryInterval: 1500
#密码,如果没有设置null或者不设置,默认为null
# password: null
#每个Redis连接限制的订阅,默认5
subscriptionsPerConnection: 5
#客户端连接名称,默认为null
clientName: null
#连接地址,一定要下面这种格式。默认本机的6379端口
address: "redis://127.0.0.1:6379"
#最小空闲Redis订阅连接数量。默认1
subscriptionConnectionMinimumIdleSize: 1
#Redis订阅连接最大池大小。默认50
subscriptionConnectionPoolSize: 50
#最小空闲Redis连接数。默认24
connectionMinimumIdleSize: 32
#Redis连接的最大池大小。默认64
connectionPoolSize: 1024
#DNS更改监视时间间隔。应用程序必须确保JVM DNS缓存TTL足够低以支持此功能。设置-1为禁用。代理模式支持单个主机名的多个IP绑定。默认5000
dnsMonitoringInterval: 5000
# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。默认当前处理核数量 * 2
threads: 16
# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。默认32
nettyThreads: 64
# 默认 org.redisson.codec.MarshallingCodec,部分编码需要引入编码对于依赖jar包。
codec: !<org.redisson.codec.JsonJacksonCodec> {}
# 传输模式,默认NIO,可选参数:
# TransportMode.NIO,
# TransportMode.EPOLL - 需要依赖里有netty-transport-native-epoll包(Linux)
# TransportMode.KQUEUE - 需要依赖里有 netty-transport-native-kqueue包(macOS)
transportMode: "NIO"
3.2 哨兵配置
sentinelServersConfig:
#如果一段timeout时间未使用池化连接,并且当前连接量大于最小空闲连接池大小,则它将关闭并从池中删除。值(以毫秒为单位)。默认10000
idleConnectionTimeout: 10000
#连接到任何Redis服务器时超时。默认10000
connectTimeout: 10000
#Redis服务器响应超时。成功发送Redis命令后,开始倒数计时。值(以毫秒为单位)。默认3000
timeout: 3000
#超时重试次数,默认3次
retryAttempts: 3
#重试的时间间隔,默认1500毫秒
retryInterval: 1500
#从可用服务器的内部列表中排除的Redis Slave重新连接尝试间隔。在每个超时事件中,Redisson都会尝试连接到已断开连接的Redis服务器。值(以毫秒为单位)默认3000
failedSlaveReconnectionInterval: 3000
#当此服务器上第一次Redis命令执行失败的时间间隔达到定义的值时,将从可用节点的内部列表中排除无法执行命令的Redis从节点。值(以毫秒为单位)。默认60000
failedSlaveCheckInterval: 60000
#密码,如果没有设置null或者不设置,默认为null
# password: null
#每个Redis连接限制的订阅
subscriptionsPerConnection: 5
#客户端名称。默认null
# clientName: null
# 在使用多个Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点:
# org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法
# org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法
# org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法
# 默认:RoundRobinLoadBalancer
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
# 长期保持一定数量的发布订阅连接是必须的。默认1
subscriptionConnectionMinimumIdleSize: 1
# 多从节点的环境里,每个从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。默认50
subscriptionConnectionPoolSize: 50
# 多从节点的环境里,每个从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。
# 长期保持一定数量的连接有利于提高瞬时读取反映速度。默认32
slaveConnectionMinimumIdleSize: 32
# 多从节点的环境里,每个从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。默认64
slaveConnectionPoolSize: 512
# 多从节点的环境里,每个主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。默认32
masterConnectionMinimumIdleSize: 32
# 多主节点的环境里,每个主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。 默认64
masterConnectionPoolSize: 512
# 设置读取操作选择节点的模式。 可用值为:
# SLAVE - 只在从服务节点里读取。 默认
# MASTER - 只在主服务节点里读取。
# MASTER_SLAVE - 在主从服务节点里都可以读取。
readMode: "SLAVE"
# 设置订阅操作选择节点的模式。可用值为:
# SLAVE - 只在从服务节点里订阅。默认
# MASTER - 只在主服务节点里订阅。
subscriptionMode: "SLAVE"
#服务器地址,一定要按这种格式配置
sentinelAddresses:
- "redis://127.0.0.1:7001"
- "redis://127.0.0.1:7002"
#Redis Sentinel服务器和主更改监视任务使用的主服务器名称。
# masterName: "mymaster"
# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。默认当前处理核数量 * 2
threads: 16
# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。默认32
nettyThreads: 64
# Redisson的对象编码类是用于将对象进行序列化和反序列化,以实现对该对象在Redis里的读取和存储。
# Redisson提供了多种的对象编码应用,以供大家选择:https://github.com/redisson/redisson/wiki/4.-data-serialization
# 默认 org.redisson.codec.MarshallingCodec,部分编码需要引入编码对于依赖jar包。
codec: !<org.redisson.codec.JsonJacksonCodec> {}
# 传输模式,默认NIO,可选参数:
# TransportMode.NIO,
# TransportMode.EPOLL - 需要依赖里有netty-transport-native-epoll包(Linux)
# TransportMode.KQUEUE - 需要依赖里有 netty-transport-native-kqueue包(macOS)
transportMode: "NIO"
3.3 集群配置
# 集群模式
clusterServersConfig:
# 如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,
# 那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。默认10000
idleConnectionTimeout: 10000
# 同节点建立连接时的等待超时。时间单位是毫秒。默认10000
connectTimeout: 10000
# 等待节点回复命令的时间。该时间从命令发送成功时开始计时。默认3000
timeout: 5000
# 命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。
# 如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。默认值3
retryAttempts: 3
# 在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。默认1500
retryInterval: 1500
# 失败从节点重连间隔时间
failedSlaveReconnectionInterval: 1000
# 失败从节点校验间隔时间
failedSlaveCheckInterval: 5000
# 用于节点身份验证的密码。默认null
password: redis1087..
# 每个连接的最大订阅数量。默认5
subscriptionsPerConnection: 5
# 在Redis节点里显示的客户端名称。默认null
clientName: redis-client
# 在使用多个Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点:
# org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法
# org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法
# org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法
# 默认:RoundRobinLoadBalancer
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
# 用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。
# 长期保持一定数量的发布订阅连接是必须的。默认1
subscriptionConnectionMinimumIdleSize: 1
# 多从节点的环境里,每个从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。默认50
subscriptionConnectionPoolSize: 50
# 多从节点的环境里,每个从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。
# 长期保持一定数量的连接有利于提高瞬时读取反映速度。默认32
slaveConnectionMinimumIdleSize: 32
# 多从节点的环境里,每个从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。默认64
slaveConnectionPoolSize: 1024
# 多从节点的环境里,每个主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。默认32
masterConnectionMinimumIdleSize: 32
# 多主节点的环境里,每个主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。 默认64
masterConnectionPoolSize: 1024
# 设置读取操作选择节点的模式。 可用值为:
# SLAVE - 只在从服务节点里读取。 默认
# MASTER - 只在主服务节点里读取。
# MASTER_SLAVE - 在主从服务节点里都可以读取。
readMode: "SLAVE"
# 设置订阅操作选择节点的模式。可用值为:
# SLAVE - 只在从服务节点里订阅。默认
# MASTER - 只在主服务节点里订阅。
subscriptionMode: "SLAVE"
# 集群节点地址
nodeAddresses:
- "redis://127.0.0.1:7001"
- "redis://127.0.0.1:7002"
- "redis://127.0.0.1:7003"
- "redis://127.0.0.1:7004"
- "redis://127.0.0.1:7005"
- "redis://127.0.0.1:7006"
# 对主节点变化节点状态扫描的时间间隔。单位是毫秒。
scanInterval: 1000
# ping连接间隔。0为禁用,默认 30000,单位毫秒
pingConnectionInterval: 30000
# 启用TCP keepAlive进行连接,默认false
keepAlive: false
# 启用TCP noDelay进行连接,默认false
tcpNoDelay: false
# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。默认当前处理核数量 * 2
threads: 16
# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。默认32
nettyThreads: 32
# Redisson的对象编码类是用于将对象进行序列化和反序列化,以实现对该对象在Redis里的读取和存储。
# Redisson提供了多种的对象编码应用,以供大家选择:https://github.com/redisson/redisson/wiki/4.-data-serialization
# 默认 org.redisson.codec.MarshallingCodec,部分编码需要引入编码对于依赖jar包。
codec: !<org.redisson.codec.JsonJacksonCodec> {}
# 传输模式,默认NIO,可选参数:
# TransportMode.NIO,
# TransportMode.EPOLL - 需要依赖里有netty-transport-native-epoll包(Linux)
# TransportMode.KQUEUE - 需要依赖里有 netty-transport-native-kqueue包(macOS)
transportMode: "NIO"
四、redisson使用
工具类
package com.lcy.base.redis.util;
import java.util.concurrent.TimeUnit;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import com.lcy.base.common.spring.SpringApplicationContext;
import lombok.extern.slf4j.Slf4j;
/**
* @Description 加锁工具类
* @Author lcy
* @Date 2021/8/20 15:07
*/
@Slf4j
public class LockUtil {
/**
* @Description 加锁操作类
* @Author lcy
* @Date 2021/8/20 15:07
*/
public interface LockOperation {
/**
* 加锁以后的操作
* @author lcy
* @date 2021/8/20 15:08
**/
void lockOperation();
}
/**
* 通过redis加锁操作
* @param lockKey 锁的key
* @param lockOperation 加锁以后的操作
* @author lcy
* @date 2021/8/20 15:12
**/
public static void lockByRedis(String lockKey,LockOperation lockOperation){
RedissonClient redissonClient = SpringApplicationContext.getBean(RedissonClient.class);
//获取锁
RLock lock = redissonClient.getLock(lockKey);
try {
lock.lock();
//加锁以后的操作
lockOperation.lockOperation();
} finally {
//释放锁
if (lock.isHekdByCurrentThread()) {
lock.unlock();
log.info("解锁成功");
}
}
}
/**
* 通过redis加锁操作,并且设置超时时间
* @param lockKey 锁的key
* @param timeout 超时时间
* @param timeUnit 超时时间单位
* @param lockOperation 加锁以后的操作
* @author lcy
* @date 2021/8/20 15:12
**/
public static void lockByRedis(String lockKey,long timeout,TimeUnit timeUnit,LockOperation lockOperation){
RedissonClient redissonClient = SpringApplicationContext.getBean(RedissonClient.class);
//获取锁
RLock lock = redissonClient.getLock(lockKey);
try {
lock.lock(timeout,timeUnit);
//加锁以后的操作
lockOperation.lockOperation();
} finally {
//释放锁
if (lock.isLocked()) {
lock.unlock();
log.info("解锁成功");
}
}
}
/**
* 通过redis加锁操作,并且设置超时时间,单位为秒
* @param lockKey 锁的key
* @param timeout 超时时间
* @param lockOperation 加锁以后的操作
* @author lcy
* @date 2021/8/20 15:12
**/
public static void lockByRedis(String lockKey,long timeout,LockOperation lockOperation){
lockByRedis(lockKey,timeout,TimeUnit.SECONDS,lockOperation);
}
}