一、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
二、redis(lettuce) 配置
spring:
redis:
database: 0
host: 192.168.249.154
port: 6379
password:
timeout: 2000s
lettuce:
pool:
max-wait: 60s
max-idle: 8
min-idle: 5
max-active: 8
三、Redis配置类
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
四、Redis分布式锁工具类
@Component
public class RedisLockUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final byte[] SCRIPT_RELEASE_LOCK = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end".getBytes();
public synchronized Boolean tryLock(String key, String requestId, long expire) {
return redisTemplate.execute((RedisCallback<Boolean>) redisConnection -> redisConnection.set(key.getBytes(), requestId.getBytes(), Expiration.from(expire, TimeUnit.SECONDS), RedisStringCommands.SetOption.SET_IF_ABSENT));
}
public synchronized Boolean releaseLock(String key, String requestId) {
return redisTemplate.execute((RedisCallback<Boolean>) redisConnection -> redisConnection.eval(SCRIPT_RELEASE_LOCK, ReturnType.BOOLEAN, 1, key.getBytes(), requestId.getBytes()));
}
}
五、使用示例
Boolean lock = redisLockUtil.tryLock(rKeyLock, requestId, 10);
if (null != lock && lock) {
try {
} finally {
Boolean release = redisLockUtil.releaseLock(rKeyLock, requestId);
}
} else {
log.warn("redis锁获取失败|{}|{}", rKeyLock, lock);
}