基于Redisson实现分布式锁

前言

最近开发了几个微服务上线了,发现定时任务执行了很多次,查看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();
        }
    }

配置文件就不上了

posted @ 2019-04-01 15:09  东北小狐狸  阅读(1114)  评论(0编辑  收藏  举报