当前位置: 首页 > news >正文

Redisson 框架详解

目录

一.为什么要使用分布式锁?

二.Redisson 的基本使用:

1.添加 Redisson 依赖:

2.在 application.yml 配置 Redis:

3. 创建 Redisson 客户端:

(1)单节点模式:

(2)集群模式:

4.注入RedissonClient:

5.使用 Redisson 存储和获取值:

三.配置集群连接池:

1. Redisson 集群连接池配置项:

2. 配置 Redis 集群的连接池:

四.如何在Boot项目中使用Redission实现分布式锁?

1.引入 Redisson 依赖:

 2.配置 Redisson:

3.在 Spring Boot 中注入 RedissonClient:

4.使用分布式锁:


Redisson 是一个基于 Redis 的高效 Java 客户端,封装了 Redis 的大部分功能,提供了更为丰富和高效的操作接口,能够帮助开发者更便捷地进行分布式缓存、分布式锁、分布式集合等操作。它不仅支持 Redis 的基本操作,还提供了更多的高级功能,如分布式锁、分布式集合、分布式计数器等,可以大大简化分布式应用的开发。

一.为什么要使用分布式锁?

分布式锁是解决 分布式系统中的资源竞争问题 的一种有效机制。在高并发分布式系统中,多个服务节点可能同时访问同一资源(如数据库、文件系统等)。这种竞争可能导致数据的不一致性、重复操作、死锁等问题,因此,使用分布式锁来保证同一时刻只有一个节点能够访问共享资源,从而确保系统的正确性和稳定性。

在单机系统中,当多个线程访问共享资源时,操作系统通常使用互斥锁(如 Java 中的 synchronizedReentrantLock)来保证同一时刻只有一个线程能访问该资源。而在分布式系统中,资源通常分布在多个服务实例或节点上,单纯的本地锁(如 synchronized)无法跨节点进行协调,因此需要分布式锁来确保不同节点间的同步。

使用分布式锁的方式:

  • 所有节点都尝试获取锁,如果一个节点获得了锁,它将执行任务。
  • 其他节点则会等待或者跳过执行该任务,避免重复执行。

使用场景:

  1. 防止多次执行相同的任务
  2. 确保分布式系统中资源的独占访问
  3. 控制并发数量

二.Redisson 的基本使用:

1.添加 Redisson 依赖:

在项目中使用 Redisson,首先需要添加 Redisson 的 Maven 依赖:

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.1</version> <!-- 请根据最新版本替换 -->
</dependency>

2.在 application.yml 配置 Redis:

# 单节点
redisson:address: redis://127.0.0.1:6379
# 集群
redisson:cluster:addresses: - redis://127.0.0.1:7000- redis://127.0.0.1:7001- redis://127.0.0.1:7002

3. 创建 Redisson 客户端:

Redisson 提供了两种方式来创建客户端:单节点模式集群模式

(1)单节点模式:

在单节点模式下,我们只需要连接到一个 Redis 实例,在配置类中:

import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.redisson.Redisson;@Configuration
public class RedissonConfig {@Beanpublic RedissonClient redissonClient() {// 配置单节点 RedisConfig config = new Config();SingleServerConfig serverConfig = config.useSingleServer();serverConfig.setAddress("redis://127.0.0.1:6379");serverConfig.setPassword("yourpassword");return Redisson.create(config);}
}

(2)集群模式:

import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ClusterServersConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.redisson.Redisson;import java.util.List;@Configuration
public class RedissonClusterConfig {// 从配置文件中读取 Redis 集群的地址@Value("${redisson.cluster.addresses}")private List<String> clusterAddresses;@Beanpublic RedissonClient redissonClient() {// 创建 Redis 配置对象Config config = new Config();// 配置集群ClusterServersConfig clusterConfig = config.useClusterServers();// 添加集群节点地址for (String address : clusterAddresses) {clusterConfig.addNodeAddress(address);}// 如果需要配置密码,使用 setPassword 方法// clusterConfig.setPassword("yourpassword");// 创建并返回 Redisson 客户端return Redisson.create(config);}
}

4.注入RedissonClient:

通过 @Autowired 注入 RedissonClient 到需要使用的服务类中。

import org.redisson.api.RedissonClient;
import org.redisson.api.RMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class RedisService {@Autowiredprivate RedissonClient redissonClient;public void demoMapUsage() {// 获取 Redis 集群中的分布式 MapRMap<String, String> map = redissonClient.getMap("myMap");map.put("name", "Alice");map.put("age", "30");System.out.println("Name: " + map.get("name"));System.out.println("Age: " + map.get("age"));}
}

5.使用 Redisson 存储和获取值:

RBucket<String> 是 Redisson 提供的一个接口,它代表 Redis 中一个字符串类型的值。我们可以通过它来存储和获取一个键值对。

import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class RedisService {@Autowiredprivate RedissonClient redissonClient;// 存储值public void setValue(String key, String value) {RBucket<String> bucket = redissonClient.getBucket(key); // 获取 Redis 中的指定 keybucket.set(value);  // 存储值}// 获取值public String getValue(String key) {RBucket<String> bucket = redissonClient.getBucket(key); // 获取 Redis 中的指定 keyreturn bucket.get(); // 获取存储的值}
}

三.配置集群连接池:

在使用 Redisson 配置 Redis 集群时,我们可以通过配置连接池来管理连接的数量、连接的超时时间等。Redisson 提供了灵活的配置方式来定制集群模式的连接池。

1. Redisson 集群连接池配置项:

Redisson 提供了多个与连接池相关的配置项,主要包括以下几个:

  • masterConnectionPoolSize:主节点连接池的大小(连接数量)。
  • slaveConnectionPoolSize:从节点连接池的大小(连接数量)。
  • connectionMinimumIdleSize:连接池中保持的最小空闲连接数。
  • connectionPoolSize:连接池的最大连接数。
  • idleConnectionTimeout:空闲连接的超时时间。
  • connectTimeout:连接的超时时间。
  • timeout:操作超时时间(请求的最大等待时间)。

2. 配置 Redis 集群的连接池:

application.yml 中配置连接池参数:

redisson:cluster:addresses: - redis://127.0.0.1:7000- redis://127.0.0.1:7001- redis://127.0.0.1:7002# 集群连接池配置master-connection-pool-size: 100      # 主节点连接池大小slave-connection-pool-size: 50       # 从节点连接池大小connection-pool-size: 200            # 总连接池大小connection-minimum-idle-size: 10     # 最小空闲连接数idle-connection-timeout: 10000       # 空闲连接超时connect-timeout: 3000                # 连接超时timeout: 5000                        # 请求超时

配置连接池是确保 Redis 集群高效运行的关键,它能够有效管理连接的数量,提高 Redis 的性能,避免频繁地创建和销毁连接。

如果我们在 application.ymlapplication.properties 文件中配置了 Redisson 的连接池参数,并且使用了 redisson-spring-boot-starter,Spring Boot 会自动读取这些配置并初始化连接池。

四.如何在Boot项目中使用Redission实现分布式锁?

在 Spring Boot 项目中使用 Redisson 实现分布式锁,主要涉及到以下几个步骤:

  1. 引入 Redisson 依赖
  2. 配置 Redisson 客户端
  3. 在 Spring Boot 中注入 RedissonClient
  4. 使用分布式锁

1.引入 Redisson 依赖:

<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.16.1</version> <!-- 请根据最新版本替换 -->
</dependency>

 2.配置 Redisson:

redisson:# Redis 集群配置cluster:# 集群节点地址,多个节点地址用逗号分隔nodes:- redis://127.0.0.1:7000- redis://127.0.0.1:7001- redis://127.0.0.1:7002- redis://127.0.0.1:7003- redis://127.0.0.1:7004- redis://127.0.0.1:7005# Redis 密码(如果有密码的话)password: yourpassword  # Redis 的密码# 连接池配置connection-pool-size: 100            # 连接池大小connection-minimum-idle-size: 10     # 最小空闲连接数idle-connection-timeout: 10000       # 空闲连接超时(毫秒)connect-timeout: 3000                # 连接超时(毫秒)timeout: 5000                        # 请求超时(毫秒)retries: 3                           # 在获取连接时的最大重试次数retry-interval: 1000                 # Redis 集群模式下的超时时间wait-timeout: 3000                   # 最大等待连接的时间(毫秒)subscription-mode: false             # 集群模式下是否启用超时管理threads: 16                          # 线程池大小

3.在 Spring Boot 中注入 RedissonClient:

在 Spring Boot 中,我们可以通过 @Autowired 注入 RedissonClient,然后在服务类中使用它进行 Redis 操作。

import org.redisson.api.RLock;
import org.redisson.api.RBucket;
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 RedisWithLockService {@Autowiredprivate RedissonClient redissonClient;// 锁的名称private static final String LOCK_KEY = "myLock";// 存储到 Redis 中的键private static final String REDIS_KEY = "userBalance";// 分布式锁处理业务逻辑public void updateBalance(String userId, double newBalance) {// 获取分布式锁RLock lock = redissonClient.getLock(LOCK_KEY);try {// 尝试获取锁,最多等待 10 秒,锁自动释放时间为 30 秒if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {// 锁获取成功,执行 Redis 操作System.out.println("Lock acquired, updating balance...");// 获取当前用户的余额double currentBalance = getUserBalanceFromRedis(userId);System.out.println("Current balance: " + currentBalance);// 更新余额(模拟业务逻辑)double updatedBalance = currentBalance + newBalance;System.out.println("Updated balance: " + updatedBalance);// 将新的余额存储回 RedissetUserBalanceToRedis(userId, updatedBalance);} else {System.out.println("Unable to acquire lock for updating balance.");}} catch (InterruptedException e) {e.printStackTrace();} finally {// 确保释放锁if (lock.isHeldByCurrentThread()) {lock.unlock();}}}// 获取用户余额(从 Redis 中)private double getUserBalanceFromRedis(String userId) {RBucket<Double> bucket = redissonClient.getBucket(REDIS_KEY + ":" + userId);return bucket.isExists() ? bucket.get() : 0.0; // 如果值存在则获取,如果没有则返回 0}// 更新用户余额(存入 Redis)private void setUserBalanceToRedis(String userId, double balance) {RBucket<Double> bucket = redissonClient.getBucket(REDIS_KEY + ":" + userId);bucket.set(balance);  // 存储新的余额}
}

4.使用分布式锁:

RedisLockService 中定义了 processWithDistributedLock 方法,调用时,Redisson 将确保在同一时刻只有一个进程/线程可以进入锁的保护区域。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class RedisWithLockController {@Autowiredprivate RedisWithLockService redisWithLockService;// 模拟调用分布式锁更新用户余额的接口@GetMapping("/updateBalance")public String updateBalance(@RequestParam String userId, @RequestParam double amount) {redisWithLockService.updateBalance(userId, amount);return "Balance update request received for user: " + userId;}
}

通过访问下面接口地址:

http://localhost:8080/updateBalance?userId=user1&amount=100

 查看后端返回数据。

总结:

  • Redisson 提供了丰富的 API 用于存储和获取 Redis 中的值。你可以通过 RBucket 等数据结构操作 Redis 中的数据。
  • 使用 分布式锁 可以确保在多个服务实例之间协调对共享资源(如 Redis 中的数据)的访问。
  • Redisson 的分布式锁非常适合用来保护 Redis 中的临界资源,避免高并发访问导致的数据不一致问题。
http://www.lryc.cn/news/511912.html

相关文章:

  • 正确导入MapStruct并避免与Lombok编译冲突的深入分析
  • K8S 黑魔法之如何从 Pod 拿到节点的命令行
  • 【bluedroid】A2dp Source播放流程源码分析(4)
  • 计算机网络 (9)数据链路层
  • kubernetes学习-集群搭建部署(一)
  • docker commit生成的镜像瘦身
  • 基于Spring Boot的宠物领养系统的设计与实现(代码+数据库+LW)
  • 7.若依参数设置、通知公告、日志管理
  • 基于FISCO BCOS的电子签署系统
  • RocketMQ(二)RocketMQ实战
  • Java重要面试名词整理(十三):RocketMQ
  • 机器学习之线性回归算法预测数据
  • Python | 如何在Matplotlib中仅绘制热图的上/下三角形
  • Leetcode经典题20--长度最小的子数组
  • 【计算机视觉】超简单!维纳滤波的经典案例
  • 【closerAI ComfyUI】快速洗图!高效快速的提示词反推节点——cliption,让洗图出图快人一步不爆显存!
  • AE Dressler CESAR 1312 Generator Model User Manual
  • 【513. 找树左下角的值 中等】
  • 网络通信的瑞士军刀:Python socket库全解析
  • 【笔记️】魔爪 Mini mx 使用快捷键
  • 去除 el-input 输入框的边框(element-ui@2.15.13)
  • Vue中的一些用法
  • 异步爬虫之协程的基本原理
  • Diffusion Transformer(DiT)——将扩散过程中的U-Net换成ViT:近频繁用于视频生成与机器人动作预测(含清华PAD详解)
  • CPT203 Software Engineering 软件工程 Pt.2 敏捷方法和需求工程(中英双语)
  • 【Git】-- 在本地执行 git fetch 发生异常
  • Apache Doris 创始人:何为“现代化”的数据仓库?
  • 高校网络安全存在的问题与对策研究
  • Redis的数据类型,线程,持久化机制
  • 什么是ondelete cascade以及使用sqlite演示ondelete cascade使用案例