Spring Boot + Redisson 实现分布式锁

使用Spring Boot集成Redisson实现分布式锁

Spring Boot是构建Java应用程序的一个流行框架,它使得应用程序的开发变得简单和高效。结合Redis和Redisson,Spring Boot可以轻松实现分布式锁。Redisson是一个高性能的Redis客户端,能够通过简洁的API提供分布式锁功能。本节将介绍如何在Spring Boot中集成Redisson,并使用它实现分布式锁。

一、在Spring Boot项目中引入Redisson依赖

首先,我们需要在Spring Boot项目中引入Redisson的依赖。你可以通过Maven或Gradle来实现。

Maven依赖配置:
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.16.6</version>
</dependency>
Gradle依赖配置:
implementation 'org.redisson:redisson:3.16.6'

二、配置Redisson客户端

在Spring Boot中使用Redisson,需要配置Redisson的Config对象。我们可以在@Configuration注解的类中配置它,或者直接在application.yml中进行配置。

1. 配置类

首先,我们创建一个配置类来初始化RedissonClient,并通过@Bean注解将它注入到Spring容器中。

import org.redisson.api.RedissonClient;
import org.redisson.api.Config;
import org.redisson.Redisson;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient() {
        // 创建Redisson配置对象
        Config config = new Config();
        // 配置Redisson连接Redis服务器的地址
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");

        // 创建Redisson客户端
        return Redisson.create(config);
    }
}
2. application.yml配置(可选)

另外,你也可以通过application.yml文件来配置Redisson连接信息。这种方式适合集中管理配置。

spring:
  redis:
    host: localhost
    port: 6379
    password: null
    timeout: 2000
    jedis:
      pool:
        max-active: 10
        max-idle: 5
        min-idle: 1
        max-wait: -1
  redisson:
    address: redis://127.0.0.1:6379
    password: null
    connection-timeout: 3000
    timeout: 3000
    retries: 3
    retry-interval: 1500

然后在配置类中读取这些配置:

import org.redisson.api.RedissonClient;
import org.redisson.api.Config;
import org.redisson.Redisson;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfig {

    @Value("${spring.redis.host}")
    private String redisHost;

    @Value("${spring.redis.port}")
    private int redisPort;

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://" + redisHost + ":" + redisPort);
        return Redisson.create(config);
    }
}

三、使用Redisson分布式锁

现在,我们已经配置好了Redisson客户端,可以开始使用它来实现分布式锁了。

1. 获取分布式锁

在Spring Boot中,我们可以通过@Autowired注解自动注入RedissonClient对象,并利用RedissonClientgetLock方法获取锁。

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class LockService {

    @Autowired
    private RedissonClient redissonClient;

    public void performTaskWithLock() {
        // 获取名为"myLock"的分布式锁
        RLock lock = redissonClient.getLock("myLock");

        try {
            // 尝试获取锁,最多等待10秒,自动释放时间为30秒
            boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
            if (isLocked) {
                System.out.println("锁已获取,开始执行任务...");
                // 执行需要保护的业务逻辑
                // 模拟任务
                Thread.sleep(5000);
            } else {
                System.out.println("无法获取锁,任务跳过");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 确保释放锁
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}
2. 控制锁的获取时间

使用tryLock()方法时,我们可以设置获取锁的等待时间和锁的自动释放时间。

  • 等待时间:即尝试获取锁的最大时间。如果在此时间内未能获取锁,则返回false
  • 自动释放时间:即锁的最大持有时间,过了这个时间后,锁会自动释放。

例如,lock.tryLock(10, 30, TimeUnit.SECONDS)表示:

  • 最多等待10秒来获取锁。
  • 获取锁后,锁将在30秒后自动释放。
3. 阻塞获取锁

如果我们希望阻塞式地获取锁直到成功,可以使用lock()方法:

public void performTaskWithBlockingLock() {
    RLock lock = redissonClient.getLock("myLock");
    lock.lock();  // 阻塞直到获取锁

    try {
        // 执行需要保护的操作
        System.out.println("锁已获取,开始执行任务...");
        // 模拟任务
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();  // 解锁
    }
}
4. 公平锁

如果希望锁能够按照请求的顺序进行分配,避免线程饥饿,可以使用公平锁。Redisson支持公平锁的实现,使用RFairLock来获取公平锁:

import org.redisson.api.RFairLock;

public void performTaskWithFairLock() {
    RFairLock fairLock = redissonClient.getFairLock("myFairLock");
    fairLock.lock();
    try {
        // 执行需要保护的操作
        System.out.println("公平锁已获取,开始执行任务...");
        // 模拟任务
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        fairLock.unlock();
    }
}

四、总结

通过结合Spring Boot和Redisson,使用分布式锁来确保分布式环境下的数据一致性和并发控制变得非常简单。我们可以通过Redisson提供的简单API,快速实现分布式锁功能,并能够灵活配置等待时间、超时时间以及公平锁等高级功能,进一步保证系统的高效与可靠。

正文到此结束
评论插件初始化中...
Loading...