前言
本篇主要介紹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();