重学SpringBoot3-集成Redis(四)之Redisson

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》

期待您的点赞👍收藏⭐评论✍

重学SpringBoot3-集成Redis(四)之Redisson

  • [1. 添加 Redisson 依赖](#1. 添加 Redisson 依赖)
  • [2. 配置 Redisson 客户端](#2. 配置 Redisson 客户端)
  • [3. 使用 Redisson 实现分布式锁](#3. 使用 Redisson 实现分布式锁)
  • [4. 调用分布式锁](#4. 调用分布式锁)
  • [5. 为什么使用Redisson分布式锁](#5. 为什么使用Redisson分布式锁)
  • [6. 常见问题](#6. 常见问题)
  • [7. 总结](#7. 总结)

在 Spring Boot 3 中,整合 Redisson 实现分布式锁可以有效地解决分布式环境下的并发问题。Redisson 是 Redis 官方推荐的客户端,它提供了丰富的分布式对象和高级功能,包括分布式锁的实现。下面介绍如何使用 Spring Boot 3 和 Redisson 来实现分布式锁的功能。

1. 添加 Redisson 依赖

首先,需要在 pom.xml 中添加 Redisson 的依赖,并确保已经引入了 Spring Boot 和 Redis 的相关依赖:

xml 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.23.4</version>
        </dependency>

2. 配置 Redisson 客户端

application.yml 文件中,配置 Redis 的连接信息,此例以单机版 Redis 为例。config: 后面跟着一个管道符 (|),表示一个多行字符串,也就是一个整体。

yaml 复制代码
spring:
  redis:
    redisson:
      config: |
        singleServerConfig:
          address: redis://localhost:6379    # Redis 连接地址,前缀为 redis://
          password: 			             # 如果 Redis 需要密码认证,则填写密码
          timeout: 3000                      # 命令执行超时时间(毫秒)

如果使用的是 Redis 集群则需要修改为如下配置:

yaml 复制代码
spring:
  redis:
    redisson: 
      config: |
        clusterServersConfig:
          password: 
          nodeAddresses:
          - redis://127.0.0.1:6379
          - redis://127.0.0.2:6379
          - redis://127.0.0.3:6379

接着,在配置类中初始化 Redisson 客户端。

java 复制代码
package com.coderjia.boot310redis.config;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.spring.starter.RedissonProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author CoderJia
 * @create 2024/10/5 下午 04:53
 * @Description
 **/
@Configuration
public class RedissonConfig {

    @Autowired
    private RedissonProperties redissonProperties;

    @Bean
    public RedissonClient redissonClient() throws Exception{
        Config config = Config.fromYAML(redissonProperties.getConfig());
        Redisson.create(config);
        System.out.println("Redisson 已启动");
        return Redisson.create(config);
    }

}

3. 使用 Redisson 实现分布式锁

通过 RedissonClient,我们可以使用分布式锁功能。下面是一个简单的示例,展示如何使用 Redisson 实现分布式锁。

java 复制代码
package com.coderjia.boot310redis.service;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author CoderJia
 * @create 2024/10/5 下午 05:14
 * @Description
 **/
@Service
public class LockService {

    private final RedissonClient redissonClient;

    public LockService(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    public void doSomethingWithLock() {
        // 获取锁对象
        RLock lock = redissonClient.getLock("myLock");

        try {
            // 尝试获取锁,等待时间 100ms,锁定时间 10秒
            if (lock.tryLock(100, 10, TimeUnit.SECONDS)) {
                try {
                    // 加锁成功,执行业务逻辑
                    System.out.println("锁定成功,正在执行关键任务...");
                    Thread.sleep(5000);  // 模拟任务执行
                } finally {
                    // 释放锁
                    lock.unlock();
                    System.out.println("任务完成,已释放锁");
                }
            } else {
                System.out.println("无法获取锁,其他线程正在执行该任务");
            }
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }
}

4. 调用分布式锁

在你的业务逻辑中调用上面创建的 LockService 方法。

java 复制代码
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LockController {

    private final LockService lockService;

    public LockController(LockService lockService) {
        this.lockService = lockService;
    }

    @GetMapping("/test-lock")
    public String testLock() {
        lockService.doSomethingWithLock();
        return "分布式锁测试完成";
    }
}

调用 curl "http://localhost:8080/test-lock?id=A" 接口,进入分布式锁执行逻辑。

开启两个线程,同时调用 curl "http://localhost:8080/test-lock?id=A"curl "http://localhost:8080/test-lock?id=B",可以看到先执行的线程占用了锁,第二个线程要等第一个线程释放锁之后才能重新获得锁。

详细说明

  1. RLock :这是 Redisson 提供的分布式锁对象。通过 RedissonClient.getLock() 方法可以获取到一个分布式锁。

  2. tryLock(long waitTime, long leaseTime, TimeUnit unit):此方法尝试获取锁,其中:

    • waitTime 是最大等待时间,表示在该时间内如果未获取到锁则放弃。
    • leaseTime 是锁的自动释放时间,避免因为业务逻辑异常导致锁无法释放。
  3. unlock():业务逻辑执行完后需要手动释放锁,否则其他线程将无法获取锁。

5. 为什么使用Redisson分布式锁

使用 Redisson 实现的分布式锁相对于直接使用 Redis 的分布式锁,具有一些显著的优势,尤其是在功能完善性、开发便捷性以及可扩展性方面。以下是 Redisson 实现的分布式锁相对于手动实现 Redis 分布式锁的几个主要优势:

优势 Redisson 实现分布式锁 手动使用 Redis 实现分布式锁
锁机制支持 可重入锁、公平锁、读写锁等丰富的锁机制 需要手动实现
锁续期机制 自动续期,防止锁超时失效 需要手动续期
操作原子性 内置保证 需要 Lua 脚本保障原子性
易用性 API 简单,易于使用和维护 需要手动编写命令逻辑
部署架构支持 支持单点、哨兵、集群模式 需要手动处理高可用
高级功能 异步、分布式对象、反压支持 需要手动封装
异步和同步支持 完善的异步和反应式支持 需要手动编写异步代码

6. 常见问题

  • 死锁问题 :如果业务逻辑执行时间超过锁的自动释放时间,会导致锁自动释放,其他线程可能会获取锁,造成数据不一致问题。为避免这种情况,可以设置足够长的 leaseTime,或者在业务逻辑完成时手动释放锁。

  • 锁竞争激烈:在高并发场景下,多个线程同时竞争锁,可能会导致部分线程长时间无法获取锁。可以通过优化锁的粒度来减少锁的竞争。

7. 总结

通过 Spring Boot 3 和 Redisson 的结合,你可以轻松实现分布式锁的功能,确保在分布式系统中关键任务的正确执行。Redisson 提供了多种锁的实现,如公平锁、读写锁、可重入锁等,能够满足不同的业务需求。

相关推荐
好奇的菜鸟1 小时前
如何在IntelliJ IDEA中设置数据库连接全局共享
java·数据库·intellij-idea
DuelCode2 小时前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis
优创学社22 小时前
基于springboot的社区生鲜团购系统
java·spring boot·后端
幽络源小助理2 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
猴哥源码2 小时前
基于Java+springboot 的车险理赔信息管理系统
java·spring boot
Hello.Reader3 小时前
Redis 延迟排查与优化全攻略
数据库·redis·缓存
YuTaoShao3 小时前
【LeetCode 热题 100】48. 旋转图像——转置+水平翻转
java·算法·leetcode·职场和发展
Dcs3 小时前
超强推理不止“大”——手把手教你部署 Mistral Small 3.2 24B 大模型
java
东阳马生架构4 小时前
订单初版—1.分布式订单系统的简要设计文档
java
Code blocks4 小时前
使用Jenkins完成springboot项目快速更新
java·运维·spring boot·后端·jenkins