1. 程式人生 > >基於Redisson實現分布式鎖

基於Redisson實現分布式鎖

解鎖 eureka 服務 factor rup edi %s etc 多實例

前言

最近開發了幾個微服務上線了,發現定時任務執行了很多次,查看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();
        }
    }

配置文件就不上了

基於Redisson實現分布式鎖