springboot整合redisson使用redis集群做分布式锁

Spring Boot集群部署时,定时任务需分布式锁竞争。在zookeeper和redis间选择,采用了redis的分布式锁轮子Redisson,单机和集群redis均可使用。同时介绍了Maven依赖、Redisson配置及使用方法,还提醒要注意服务器时间一致,避免定时任务多次执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springboot整合redisson使用redis集群做分布式锁

说明

springboot集群部署时,定时任务存在多份,所以需要一个分布式锁来进行竞争,在zookeeper和redis之间选择,最后公司大佬磊哥说redis有个分布式锁的轮子redission,然后就去了解然后用了。单机redis和集群redis都可以使用

maven依赖

 <!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.13.6</version>
        </dependency>

Redisson配置

yml配置

redisson:
	#地址
    address: "xx.xx.xx.xxx:8000,xx.xx.xx.xxx:8001,xx.xx.xx.xxx:8002"
    #尝试时间
    try-time: 0
    #锁的时间
    lock-time: 4
    #redis密码
    password:
    #扫描间隔
    scanInterval: 2000
    #命令失败重试次数
    retryAttempts: 5
    #超时时间
    timeout: 10000

client配置

@Configuration
public class RedissonConfig {
    @Value(value = "${spring.redisson.address}")
    private String redissonAddress;

    @Value(value = "${spring.redisson.password}")
    private String redissonPassword;

    @Value(value = "${spring.redisson.scanInterval}")
    private int redissonScanInterval;

    @Value(value = "${spring.redisson.retryAttempts}")
    private int redissonRetryAttempts;

    @Value(value = "${spring.redisson.timeout}")
    private int redissonTimeout;

    @Bean
    public RedissonClient getRedisClient() {
        String[] nodes = redissonAddress.split(",");
        for (int i = 0; i < nodes.length; i++) {
            nodes[i] = "redis://" + nodes[i];
        }

        Config config = new Config();
        config.useClusterServers() //这是用的集群server
                .setScanInterval(redissonScanInterval) //设置集群状态扫描时间
                .addNodeAddress(nodes).setRetryAttempts(redissonRetryAttempts).setTimeout(redissonTimeout);
        if (StringUtils.isNotEmpty(redissonPassword)) {
            config.useClusterServers().setPassword(redissonPassword);
        }
        return Redisson.create(config);
    }

}

使用

{
//        log.info("一次最多推送{}条数据", baseProperties.getPushDataNumber());
        //先判断是否有权限推送
        RLock taskLock = redissonClient.getLock(baseProperties.getPushDataLockName());
        // 支持过期解锁功能,10秒钟以后自动解锁, 无需调用unlock方法手动解锁 lock.lock(10, TimeUnit.SECONDS);
        // 尝试加锁,最多等待0秒,上锁以后4秒自动解锁
        try {
            boolean isLock = taskLock.tryLock(baseProperties.getRedssionTryTime(), baseProperties.getRedssionLockTime(), TimeUnit.SECONDS);
            // 判断是否获取锁
            if (!isLock) {
                // 获取失败
//                log.info("获取锁失败,不执行定时任务");
                return;
            }
            try {
//                log.info("获取锁成功,执行定时任务。");
                // 执行任务
                pushDataTaskExec();
            } finally {
                // 释放锁
                taskLock.unlock();
//                log.info("任务执行完毕,释放锁");
            }

        } catch (InterruptedException e) {
            log.error("定时任务获取分布式锁异常", e);
        }

    }

最后

集群部署springboot应用时需要注意服务器时间是否一致,否则还是容易造成多台服务器定时任务多次执行的问题。

### Spring Boot整合Redisson实现分布式锁集群配置示例 在Spring Boot项目中,通过Redisson可以方便地实现分布式锁功能。以下是一个完整的集群配置示例,包括依赖引入、配置文件设置以及代码实现。 #### 1. 引入Redisson依赖 确保使用的是3.18及以上版本以避免内存泄漏问题[^3]。在`pom.xml`中添加以下依赖: ```xml <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.18.1</version> </dependency> ``` #### 2. 配置Redis集群信息 在`application.yml`或`application.properties`中配置Redis集群地址和相关参数。以下是`application.yml`的示例配置: ```yaml spring: redis: cluster: nodes: - 192.168.1.101:7000 - 192.168.1.102:7001 - 192.168.1.103:7002 max-redirects: 3 timeout: 3000 password: your_redis_password ``` #### 3. Redisson配置类 创建一个配置类用于初始化RedissonClient。通过`RedissonConfig`对象定义集群模式下的连接信息。 ```java import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.ClusterServersConfig; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RedissonConfig { @Bean public RedissonClient redissonClient() { Config config = new Config(); ClusterServersConfig clusterServersConfig = config.useClusterServers() .addNodeAddress("redis://192.168.1.101:7000") .addNodeAddress("redis://192.168.1.102:7001") .addNodeAddress("redis://192.168.1.103:7002") .setPassword("your_redis_password") // 如果有密码 .setTimeout(3000); // 设置超时时间 return Redisson.create(config); } } ``` #### 4. 分布式锁代码实现 以下是一个简单的分布式锁示例,展示如何在业务逻辑中使用Redisson分布式锁。 ```java 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 DistributedLockService { @Autowired private RedissonClient redissonClient; public void executeWithLock(String lockName) { RLock lock = redissonClient.getLock(lockName); try { boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS); // 尝试获取锁,等待10秒,持有30秒 if (isLocked) { System.out.println("成功获取锁:" + lockName); // 执行业务逻辑 Thread.sleep(5000); // 模拟业务处理 System.out.println("完成业务处理"); } else { System.out.println("未能获取锁:" + lockName); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("线程被中断:" + e.getMessage()); } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); // 释放锁 System.out.println("释放锁:" + lockName); } } } } ``` #### 5. 测试分布式锁功能 可以通过多线程或多实例的方式测试分布式锁的效果。例如,在多个服务实例中调用`executeWithLock`方法,观察是否能够正确地控制并发访问。 --- ### 注意事项 - 确保Redis集群已正确部署并运行。 - 在高并发场景下,合理设置锁的等待时间和持有时间,避免死锁或资源浪费。 - 使用集群模式时,确保所有节点的网络连通性良好,并配置适当的超时时间[^1]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值