Redisson
Spring Boot快速集成Redisson
使用redisson-spring-boot-starter快速上手,Redisson支持Redis 2.8以上版本,支持Java1.6+以上版本。
pom.xml
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.13.3</version>
</dependency>
application.yml
spring:
profiles: dev
redis:
redisson:
config: classpath:redisson-dev.yaml
redisson-dev.yaml
singleServerConfig: # 单实例模式
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 1
clientName: null
address: "redis://127.0.0.1:6379"
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 1
connectionMinimumIdleSize: 1
connectionPoolSize: 5
database: 0
dnsMonitoringInterval: 5000
threads: 1
nettyThreads: 1
codec: null
transportMode: "NIO"
lockWatchdogTimeout: 30000 # 监控锁的看门狗超时,单位:毫秒
Redisson支持以下模式
通用参数
threads
默认值:16
在RTopic
对象的所有侦听器RRemoteService
,RTopic
对象和RExecutorService
任务的调用处理程序之间共享的线程数量。
nettyThreads
默认值:32
Redisson使用的所有Redis客户端之间共享的线程数量。Redis响应解码和命令发送中使用的Netty线程。0
=cores_amount * 2
codec
Redis数据编解码器。在读写Redis数据期间使用。几种实现方式提供。
transportMode
默认值: TransportMode.NIO
可用值:
TransportMode.NIO
TransportMode.EPOLL
- 需要netty-transport-native-epoll
在类路径
TransportMode.KQUEUE
- 需要netty-transport-native-kqueue
在类路径
lockWatchdogTimeout(监控锁的看门狗超时,单位:毫秒)
默认值:30000
监控锁的看门狗超时时间单位为毫秒。该参数只适用于分布式锁的加锁请求中未明确使用leaseTimeout
参数的情况。如果该看门狗未使用lockWatchdogTimeout
去重新调整一个分布式锁的lockWatchdogTimeout
超时,那么这个锁将变为失效状态。这个参数可以用来避免由Redisson客户端节点宕机或其他原因造成死锁的情况。
分布式锁
可重入锁
lock
/**
* RLock分布式可重入锁,接口场景并发测试
* @return
*/
@RequestMapping("lock2")
public R lock2() {
RLock lock = redissonClient.getLock("redisson_lock2");
lock.lock();
lock.unlock();
return R();
}
Redisson客户端节点宕机或出现异常会造成死锁,为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒,可修改配置参数lockWatchdogTimeout来重新指定。
指定自动解锁时间
注意:如果设置自动解锁时间,那么看门狗就失效了
// Redisson可通过加锁的方法提供的leaseTime的参数来指定加锁的时间,超过这个时间后锁便自动解开。
lock.lock(10, TimeUnit.SECONDS);
tryLock
/**
* RLock分布式可重入锁,tryLock
*
* @return
*/
@RequestMapping("lock5")
public R lock5() throws InterruptedException {
RLock lock = redissonClient.getLock("redisson_lock5");
boolean getLockOK = lock.tryLock();
if (getLockOK) {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
} finally {
lock.unlock();
}
return R("获取到锁");
} else {
return R("没有获取到锁");
}
}
lock -> 调用后一直阻塞到获得锁
tryLock -> 尝试是否能获得锁 如果不能获得立即返回
lockInterruptibly -> 调用后一直阻塞到获得锁 但是接受中断信号
synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock 在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock 时需要在 finally块中释放锁。