1,springboot集成redisson的时候,当redis为单节点时,直需要引入redisson的jar即可使用。
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.4</version>
</dependency>
附:redisLockUtils代码
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* Created by KS15432 on 2021/11/11.
*/
@Component
public class RedisLockUtil {
private final Logger logger = LoggerFactory.getLogger(RedisLockUtil.class);
@Autowired
private RedissonClient redissonClient;
/* @Autowired
public RedisLockUtil(@Qualifier("customRedisson") RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}*/
/**
* 加锁
* @param key 锁的 key
* @param value value ( key + value 必须保证唯一)
* @param expire key 的过期时间,单位 ms
* @param retryTimes 重试次数,即加锁失败之后的重试次数
* @param retryInterval 重试时间间隔,单位 ms
* @return 加锁 true 成功
*/
public RLock lock(String key, String value, long expire, int retryTimes, long retryInterval) {
logger.info("locking... redisK = {}", key);
RLock fairLock = redissonClient.getFairLock(key + ":" + value);
try {
boolean tryLock = fairLock.tryLock(0, expire, TimeUnit.MILLISECONDS);
if (tryLock) {
logger.info("locked... redisK = {}", key);
return fairLock;
} else {
//重试获取锁
logger.info("retry to acquire lock: [redisK = {}]", key);
int count = 0;
while(count < retryTimes) {
try {
Thread.sleep(retryInterval);
tryLock = fairLock.tryLock(0, expire, TimeUnit.MILLISECONDS);
if(tryLock) {
logger.info("locked... redisK = {}", key);
return fairLock;
}
logger.warn("{} times try to acquire lock", count + 1);
count++;
} catch (Exception e) {
logger.error("acquire redis occurred an exception", e);
break;
}
}
logger.info("fail to acquire lock {}", key);
}
} catch (Throwable e1) {
logger.error("acquire redis occurred an exception", e1);
}
return fairLock;
}
/**
* 加锁
* @param key 锁的 key
* @param value value ( key + value 必须保证唯一)
* @param expire key 的过期时间,单位 ms
* @param retryTimes 重试次数,即加锁失败之后的重试次数
* @param retryInterval 重试时间间隔,单位 ms
* @return 加锁 true 成功
*/
public boolean lock2(String key, String value, long expire, int retryTimes, long retryInterval) {
logger.info("locking... redisK = {}", key);
RLock fairLock = redissonClient.getFairLock(key + ":" + value);
try {
boolean tryLock = fairLock.tryLock(0, expire, TimeUnit.MILLISECONDS);
if (tryLock) {
logger.info("locked... redisK = {}", key);
return true;
} else {
//重试获取锁
logger.info("retry to acquire lock: [redisK = {}]", key);
int count = 0;
while(count < retryTimes) {
try {
Thread.sleep(retryInterval);
tryLock = fairLock.tryLock(0, expire, TimeUnit.MILLISECONDS);
if(tryLock) {
logger.info("locked... redisK = {}", key);
return true;
}
logger.warn("{} times try to acquire lock", count + 1);
count++;
} catch (Exception e) {
logger.error("acquire redis occurred an exception", e);
break;
}
}
logger.info("fail to acquire lock {}", key);
return false;
}
} catch (Throwable e1) {
logger.error("acquire redis occurred an exception", e1);
return false;
}
}
/**
* 加锁
* @param key 锁的 key
* @param value value ( key + value 必须保证唯一)
* @param expire key 的过期时间,单位 ms
* @return 加锁 true 成功
*/
public boolean lockCheck(String key, String value, long expire) {
logger.info("locking... redisK = {}", key);
RLock fairLock = redissonClient.getFairLock(key + ":" + value);
boolean tryLock = false;
try {
tryLock = fairLock.tryLock(0, expire, TimeUnit.MILLISECONDS);
} catch (Throwable e1) {
logger.error("acquire redis occurred an exception", e1);
}
return tryLock;
}
/**
* 释放KEY
* @return 释放锁 true 成功
*/
public boolean unlock(String key, String value) {
RLock fairLock = redissonClient.getFairLock(key + ":" + value);
try {
//如果这里抛异常,后续锁无法释放
if (fairLock.isLocked()) {
fairLock.unlock();
logger.info("release lock success");
return true;
}
} catch (Throwable e) {
logger.error("release lock occurred an exception", e);
}
return false;
}
}
2,当redis为集群模式时,即springboot配置文件为这种cluster配置时,此时用redisson会出现错误。
redis:
cluster:
nodes: 10.200.56.89:6379,10.200.56.89:6380,10.200.56.89:6381,10.200.56.93:6379,10.200.56.93:6380,10.200.56.93:6381
需要增加配置文件:RedissonConfiguration
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.beans.factory.annotation.Autowired;
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 java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Configuration
public class RedissonConfiguration {
@Autowired
private RedisProperties redisProperties;
/**
* 初始化RedissonClient客户端
* 注意:
* 此实例集群为3节点,各节点1主1从
* 集群模式,集群节点的地址须使用“redis://”前缀,否则将会报错。
*
* @return {@link RedissonClient}
*/
@Bean
public RedissonClient getRedissonClient() {
Config config = new Config();
if (redisProperties.getCluster() != null) {
//集群模式配置
List<String> nodes = redisProperties.getCluster().getNodes();
List<String> clusterNodes = new ArrayList<>();
for (int i = 0; i < nodes.size(); i++) {
clusterNodes.add("redis://" + nodes.get(i));
}
ClusterServersConfig clusterServersConfig = config.useClusterServers()
.addNodeAddress(clusterNodes.toArray(new String[clusterNodes.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);
}
}
注:其中部分代码有参考其他博文的地方,源地址已忘记,侵删,不好意思,谢谢。
如有错误的地方望指正,谢谢。
|