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 中的 synchronized
或 ReentrantLock
)来保证同一时刻只有一个线程能访问该资源。而在分布式系统中,资源通常分布在多个服务实例或节点上,单纯的本地锁(如 synchronized
)无法跨节点进行协调,因此需要分布式锁来确保不同节点间的同步。
使用分布式锁的方式:
- 所有节点都尝试获取锁,如果一个节点获得了锁,它将执行任务。
- 其他节点则会等待或者跳过执行该任务,避免重复执行。
使用场景:
- 防止多次执行相同的任务
- 确保分布式系统中资源的独占访问
- 控制并发数量
二.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.yml
或application.properties
文件中配置了 Redisson 的连接池参数,并且使用了redisson-spring-boot-starter
,Spring Boot 会自动读取这些配置并初始化连接池。
四.如何在Boot项目中使用Redission实现分布式锁?
在 Spring Boot 项目中使用 Redisson 实现分布式锁,主要涉及到以下几个步骤:
- 引入 Redisson 依赖
- 配置 Redisson 客户端
- 在 Spring Boot 中注入
RedissonClient
- 使用分布式锁
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 中的临界资源,避免高并发访问导致的数据不一致问题。
相关文章:
Redisson 框架详解
目录 一.为什么要使用分布式锁? 二.Redisson 的基本使用: 1.添加 Redisson 依赖: 2.在 application.yml 配置 Redis: 3. 创建 Redisson 客户端: (1)单节点模式: (…...
正确导入MapStruct并避免与Lombok编译冲突的深入分析
正确导入MapStruct并避免与Lombok编译冲突的深入分析 一、MapStruct与Lombok概述 1.1 MapStruct简介 MapStruct是一个代码生成器,它基于约定优于配置的原则,通过注解处理器在编译时自动生成源代码,实现对象之间的属性映射。MapStruct的优势在于减少样板代码,提高开发效率…...
K8S 黑魔法之如何从 Pod 拿到节点的命令行
搞 K8S 运维的时候,偶尔会遇到一个难题,定位到问题出在某个节点上,而由于权限审批,错误配置等等各种原因,没有办法拿到节点的 SSH 权限,无法进入节点命令行进一步排障。 这个时候,就可以用这个…...
【bluedroid】A2dp Source播放流程源码分析(4)
接上集分析:【bluedroid】A2dp Source播放流程源码分析(3)-CSDN博客 蓝牙和AUDIO之间的接口 蓝牙和audio之间的通信是通过socket,管理socket中的文件是UIPC,UIPC管理两条socket。 A2DP_CTRL_PATH /data/misc/bluedroid/.a2dp_ctrl A2DP_DATA_PATH /data/misc/bluedroid…...

计算机网络 (9)数据链路层
前言 计算机网络中的数据链路层(Data Link Layer)是OSI(开放系统互连)参考模型中的第二层,位于物理层和网络层之间。它在物理层提供的服务基础上,负责在相邻节点之间建立、维护和终止链路,确保数…...

kubernetes学习-集群搭建部署(一)
一、开三台虚拟机进行试验(centos7) 1、初始操作 # 关闭防火墙 systemctl stop firewalld systemctl disable firewalld# 关闭selinux sudo sed -i s/enforcing/disabled/ /etc/selinux/config # 永久 setenforce 0 # 临时# 关闭swap sudo swapoff -a # 临时 s…...
docker commit生成的镜像瘦身
1、清除宿主系统的docker资源 docker system prune -a --volumes 2、清理容器内系统的临时文件和缓存 # 删除包管理器缓存 apt-get clean rm -rf /var/lib/apt/lists/* # 删除日志文件 rm -rf /var/log/* # 删除临时文件 rm -rf /tmp/* 3、安装docker squash工具࿰…...

基于Spring Boot的宠物领养系统的设计与实现(代码+数据库+LW)
摘 要 如今社会上各行各业,都在用属于自己专用的软件来进行工作,互联网发展到这个时候,人们已经发现离不开了互联网。互联网的发展,离不开一些新的技术,而新技术的产生往往是为了解决现有问题而产生的。针对于宠物领…...

7.若依参数设置、通知公告、日志管理
参数设置 对系统中的参数进行动态维护。 关闭验证码校验功能 打开页面注册功能 需要修改前端页面代码 通知公告 促进组织内部信息传递 若依只提供了一个半成品,只实现了管理员可以添加通知公告。 日志管理 追踪用户行为和系统运行状况。 登录日志 和操作日志…...

基于FISCO BCOS的电子签署系统
概述 本项目致力于构建一个安全、高效且功能完备的电子签署系统,通过整合区块链技术与传统数据库管理,为用户提供了可靠的电子签署解决方案,有效应对传统电子签署系统的数据安全隐患,满足企业和个人在数字化办公环境下对电子文档…...

RocketMQ(二)RocketMQ实战
文章目录 一、RocketMQ实战1.1 批量消息发送1.2 消息发送队列自选择1.3 事务消息1.4 SpringCloud集成RocketMQ 二、最佳实践2.1 生产者2.1.1 发送消息注意事项2.1.2 消息发送失败处理方式 2.2 消费者2.2.1 消费过程幂等2.2.2 消费打印日志 2.3 Broker 三、相关问题3.1 为什么要…...
Java重要面试名词整理(十三):RocketMQ
文章目录 简述环境搭建分布式集群配置升级高可用集群 RocketMQ的消息模型基本流程消息确认机制广播消息顺序消息机制延迟消息批量消息过滤消息事务消息ACL权限控制机制 调优消费者端进行幂等控制 核心客户端负载均衡Consumer负载均衡 消息持久化设计Dleger集群的文件同步机制 简…...

机器学习之线性回归算法预测数据
机器学习之线性回归算法预测数据 目录 机器学习之线性回归算法预测数据线性回归算法概念理解算法导入线性回归模型参数理解误差项分析 LinearRegression理解参数理解返回值方法基本格式 预测一元线性回归数据问题及理解可视化数据理解数据预测 预测二元线性回归数据问题及理解数…...

Python | 如何在Matplotlib中仅绘制热图的上/下三角形
热图是一种强大的可视化工具,用于以矩阵格式表示数据,其中各个值由颜色表示。它们对于可视化相关矩阵特别有用,其中矩阵的对称性质使得显示上下三角形变得多余。本文将指导您使用Matplotlib(Python中流行的绘图库)仅绘…...

Leetcode经典题20--长度最小的子数组
题目描述 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的子数组 [numsl, numsl1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。 输入输出示例 输入&…...

【计算机视觉】超简单!维纳滤波的经典案例
Hey小伙伴们!今天来给大家分享一个 计算机视觉 中非常经典且实用的技术——维纳滤波(Wiener Filter)。维纳滤波是一种基于最小均方误差准则的滤波方法,广泛应用于图像去噪、模糊恢复等领域。它不仅可以有效去除图像中的噪声&#…...

【closerAI ComfyUI】快速洗图!高效快速的提示词反推节点——cliption,让洗图出图快人一步不爆显存!
添加图片注释,不超过 140 字(可选) 【closerAI ComfyUI】快速洗图!高效快速的提示词反推节点——cliption,让洗图出图快人一步不爆显存! 大家好,我是Jimmy。反推提示词的节点有很多,像Florence2 、Joycaption2、喵手等。都是非常优秀的。但是呢,就是占用设备资源,加…...

AE Dressler CESAR 1312 Generator Model User Manual
AE Dressler CESAR 1312 Generator Model User Manual...

【513. 找树左下角的值 中等】
题目: 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7 提示: 二叉树的节点个数的范围是 …...

网络通信的瑞士军刀:Python socket库全解析
文章目录 网络通信的瑞士军刀:Python socket库全解析背景库介绍安装与重要性简单库函数使用方法场景应用常见Bug及解决方案总结 网络通信的瑞士军刀:Python socket库全解析 背景 在现代编程中,网络通信是不可或缺的一部分。无论是构建客户端…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...