redission封装,分布式锁使用
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.16.2</version></dependency>
springboot版本是2.7.11
spring:redis:host: 192.168.12.36port: 6379password: xxxxx# 连接超时时间(毫秒)timeout: 3000ms
/*** redisson分布式锁配置** @author xxx* @date 2024/8/2*/
@Configuration
public class RedissonConfig {@Value("${spring.redis.host}")private String host;@Value("${spring.redis.port}")private String port;@Value("${spring.redis.password}")private String password;@Beanpublic RedissonClient redissonClient() {Config config = new Config();config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password);return Redisson.create(config);}
}
工具类封装
@Component
public class RedissonUtil {private static final Logger log = LoggerFactory.getLogger(RedissonUtil.class);@Resourceprivate RedissonClient redissonClient;/*** 获取分布式锁** @param lockKey 锁的唯一标识* @return 分布式锁对象*/public RLock getLock(String lockKey) {return redissonClient.getLock(lockKey);}/*** 尝试获取分布式锁(阻塞式)** @param lockKey 锁的唯一标识* @param waitTime 等待锁的最大时间(单位:秒)* @param leaseTime 锁的持有时间(单位:秒)* @return 是否成功获取锁*/public boolean tryLock(String lockKey, long waitTime, long leaseTime) {try {RLock lock = getLock(lockKey);return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);} catch (Exception e) {Thread.currentThread().interrupt();throw new RuntimeException("尝试获取锁时被中断", e);}}/*** 释放分布式锁** @param lockKey 锁的唯一标识*/public void unlock(String lockKey) {RLock lock = getLock(lockKey);if (lock.isHeldByCurrentThread()) {lock.unlock();}}/*** 加锁并执行任务(自动释放锁)** @param lockKey 锁的唯一标识* @param task 需要执行的任务*/public void executeWithLock(String lockKey, Runnable task) {RLock lock = getLock(lockKey);lock.lock();try {task.run();} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}}}/*** 尝试加锁并执行任务(自动释放锁)** @param lockKey 锁的唯一标识* @param waitTime 等待锁的最大时间(单位:秒)* @param leaseTime 锁的持有时间(单位:秒)* @param task 需要执行的任务* @return 是否成功获取锁并执行任务*/public boolean tryExecuteWithLock(String lockKey, long waitTime, long leaseTime, Runnable task) {RLock lock = getLock(lockKey);try {if (lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS)) {try {task.run();return true;} catch (Exception e) {LogUtil.error(log, "tryExecuteWithLock", "tryExecuteWithLock执行失败: {}", e.getMessage(), e);throw e; // 抛出异常以便调用方处理} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}}}} catch (InterruptedException e) {Thread.currentThread().interrupt();LogUtil.error(log, "tryExecuteWithLock", "tryExecuteWithLock尝试获取锁时被中断: {}", e.getMessage(), e);throw new RuntimeException("tryExecuteWithLock尝试获取锁时被中断", e);}return false;}
}
// 生成分布式锁的keyString lockKey = "createLinuxUserLock:" + detailPO.getTicketNumber();int maxRetries = 10; // 最大重试次数int retryCount = 0; // 当前重试次数// 循环重试获取锁while (retryCount < maxRetries) {// 尝试获取分布式锁并执行boolean success = redissonUtil.tryExecuteWithLock(lockKey, 2, 6, () -> {//业务代码});// 如果成功获取锁并执行完毕,返回trueif (success) {return true;}// 重试次数加1retryCount++;// 如果还没到最大重试次数,休眠后继续重试if (retryCount < maxRetries) {try {// 随机生成1-10秒之间的休眠时间long sleepTime = new Random().nextInt(10) * 1000 + 1;LogUtil.info(log, "createLinuxUser", "获取分布式锁失败,将在{}毫秒后重试,当前重试次数:{}", sleepTime , retryCount);Thread.sleep(sleepTime);} catch (InterruptedException e) {LogUtil.error(log, "createLinuxUser", "线程休眠异常:{}", e);Thread.currentThread().interrupt(); // 恢复中断状态return false;}}}// 达到最大重试次数仍未获取锁,抛出异常throw new BusinessException("获取分布式锁失败,已达到最大重试次数(" + maxRetries + "),无法进行堡垒机授权,请联系管理员重试");