前言

最近开发了几个微服务上线了,发现定时任务执行了很多次,查看rancher发现这几个微服务都是多实例的,也就是说定时任务执行了多次,恰好所用框架中使用的是Redisson, 正好记录下使用Redission实现分布式锁

正文

配置

添加Redisson依赖

        <dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.5</version>
</dependency>

添加配置类

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class RedissonConfiguration { @Value("${spring.redis.host}")
private String host; @Value("${spring.redis.password}")
private String password; @Value("${spring.redis.port:6379}")
private String port; @Value("${spring.redis.clientName:${eureka.instance.instanceId}}")
private String clientName; @Value("${spring.redis.idleConnectionTimeout:10000}")
private int idleConnectionTimeout; @Value("${spring.redis.pingTimeout:1000}")
private int pingTimeout; @Value("${spring.redis.connectTimeout:10000}")
private int connectTimeout; @Value("${spring.redis.timeout:3000}")
private int timeout; @Value("${spring.redis.retryAttempts:3}")
private int retryAttempts; @Value("${spring.redis.retryInterval:1500}")
private int retryInterval; @Value("${spring.redis.subscriptionsPerConnection:5}")
private int subscriptionsPerConnection; @Value("${spring.redis.subscriptionConnectionMinimumIdleSize:1}")
private int subscriptionConnectionMinimumIdleSize; @Value("${spring.redis.subscriptionConnectionPoolSize:10}")
private int subscriptionConnectionPoolSize; @Value("${spring.redis.connectionMinimumIdleSize:32}")
private int connectionMinimumIdleSize; @Value("${spring.redis.connectionPoolSize:64}")
private int connectionPoolSize; @Value("${spring.redis.database:1}")
private int database; @Value("${spring.redis.dnsMonitoring:false}")
private boolean dnsMonitoring; @Value("${spring.redis.dnsMonitoringInterval:5000}")
private int dnsMonitoringInterval; @Bean
public RedissonClient redisson() {
Config config = new Config(); config.useSingleServer()
.setAddress(String.format("redis://%s:%s", host,port))
.setClientName(clientName)
.setPassword(password)
.setIdleConnectionTimeout(idleConnectionTimeout)
.setPingTimeout(pingTimeout)
.setConnectTimeout(connectTimeout)
.setTimeout(timeout)
.setRetryAttempts(retryAttempts)
.setRetryInterval(retryInterval)
.setSubscriptionsPerConnection(subscriptionsPerConnection)
.setSubscriptionConnectionMinimumIdleSize(subscriptionConnectionMinimumIdleSize)
.setSubscriptionConnectionPoolSize(subscriptionConnectionPoolSize)
.setConnectionMinimumIdleSize(connectionMinimumIdleSize)
.setConnectionPoolSize(connectionPoolSize)
.setDatabase(database)
.setDnsMonitoring(dnsMonitoring)
.setDnsMonitoringInterval(dnsMonitoringInterval);
return Redisson.create(config);
}
}

使用

    @Inject
RedissonClient redisson; RLock lock; public void method() {
try {
// key替换为锁key, 不要与其他锁key冲突
lock = redisson.getLock("key");
// 参数1为等待时间,超时return
// 参数2为锁的过期时间
// 参数3为时间单位
// 本例中,得不到锁立即失败,50秒后自动解锁
if (!lock.tryLock(0, 50, TimeUnit.SECONDS)) {
return;
} // 业务逻辑 lock.forceUnlock(); } catch (InterruptedException e) {
// 重置线程打断状态
Thread.currentThread().interrupt();
}
}
04-24 21:02