前言
本篇主要介绍Redisson分布式锁的配置,项目结构Springboot
Maven配置
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <!-- 备注:spring-boot-data-redis默认使用luttuce连接池---> <!-- 备注:这里将luttuce连接池替换为jedis连接池---> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.5</version>
</dependency>
yml文件配置
注意:这里介绍单节点方式和集群方式的两种配置
//单节点配置 redis: host: x.x.x.x port: 6379 password: xxxx database: 1 timeout: 1000ms jedis: pool: max-active: 10 max-wait: -1ms max-idle: 8 min-idle: 0
//集群节点配置(cluster模式) 三主三从 redis: database: 1 timeout: 1000ms jedis: pool: max-active: 8 max-wait: -1ms max-idle: 8 min-idle: 0 cluster: nodes: - a.a.a.a:port1 - b.b.b.b:port2 - c.c.c.c:port3 - d.d.d.d:port4 - e.e.e.e:port5 - f.f.f.f:port6
配置类
package com.nn.status.config; import lombok.extern.slf4j.Slf4j; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.ClusterServersConfig; import org.redisson.config.Config; import org.redisson.config.SingleServerConfig; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; import java.util.List; import java.util.stream.Collectors; /** * @author Sam.yang * @since 2021/7/23 09:46 */ @Slf4j @Configuration @EnableConfigurationProperties(RedisProperties.class) public class RedissonConfiguration { /** * 初始化RedissonClient客户端 * 注意: * 此实例集群为3节点,各节点1主1从 * 集群模式,集群节点的地址须使用“redis://”前缀,否则将会报错。 * * @param redisProperties {@link RedisProperties} * @return {@link RedissonClient} */ @Bean public RedissonClient getRedissonClient(RedisProperties redisProperties) { Config config = new Config(); if (redisProperties.getCluster() != null) { //集群模式配置 List<String> nodes = redisProperties.getCluster().getNodes(); nodes = nodes.stream().map(node -> "redis://" + node).collect(Collectors.toList()); ClusterServersConfig clusterServersConfig = config.useClusterServers(); clusterServersConfig.addNodeAddress(nodes.toArray(new String[nodes.size()])); if (!StringUtils.isEmpty(redisProperties.getPassword())) { clusterServersConfig.setPassword(redisProperties.getPassword()); } } else { //单节点配置 String address = "redis://" + redisProperties.getHost() + ":" + redisProperties.getPort(); SingleServerConfig serverConfig = config.useSingleServer(); serverConfig.setAddress(address); if (!StringUtils.isEmpty(redisProperties.getPassword())) { serverConfig.setPassword(redisProperties.getPassword()); } serverConfig.setDatabase(redisProperties.getDatabase()); } //看门狗的锁续期时间,默认30000ms,这里配置成15000ms config.setLockWatchdogTimeout(15000); return Redisson.create(config); } }
DEMO
//拿锁失败时会不停的重试 RLock lock = redissonClient.getLock("serviceKey"); lock.lock(); //具有Watch Dog自动延期机制 默认续30s 每隔30/3=10 秒续到30s boolean res1 = lock.tryLock(10, TimeUnit.SECONDS); //返回false:表示尝试拿锁10s,仍然没有获取到锁,停止重试 //返回true: 表示已经获取到锁,默认具备WatchDog自动延期机制,续30s lock.lock(10, TimeUnit.SECONDS); //指定了释放时间,WatchDog不生效,10s后自动释放, boolean res2 = lock.tryLock(100, 10, TimeUnit.SECONDS); //尝试拿锁100s后停止重试,返回false,指定WatchDog,10s后自动释放 Thread.sleep(40000L); lock.unlock();