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.rhkb.cn/news/497494.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++Primer 控制流

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

RJ45网口模块设计

1、以太网概述及RJ45实物 2、常用网口信号介绍 3、RJ45网口布局布线要点分析 4、总结 1、变压器下面需要进行挖空处理&#xff0c;以免底下的铜引入干扰&#xff0c;&#xff08;将多边形挖空区域的所在层设置为Multi-Layer多层&#xff09; 2、为了更直观的看一个类中线的长…

Metagenome宏基因组,未识别的物种unclassified

1&#xff1a;"Bacteria|Proteobacteria|Betaproteobacteria|Neisseriales|Neisseriaceae|Kingella" 2&#xff1a;"Bacteria|Proteobacteria|Betaproteobacteria|Neisseriales|Neisseriaceae|unclassified" # 未识别到的/未注解到的…

深度学习笔记1:神经网络与模型训练过程

参考博客&#xff1a;PyTorch深度学习实战&#xff08;1&#xff09;——神经网络与模型训练过程详解_pytorch 实战-CSDN博客 人工神经网络 ANN&#xff1a;张量及数学运算的集合&#xff0c;排列方式近似于松散的人脑神经元排列 组成 1&#xff09;输入层 2&#xff09;隐…

【多模态】从零学习多模态——2024学习笔记总结

从零学习多模态——2024学习笔记总结 前言1. preliminary2. Transformer和NLP基础3. 多模态模型原理和架构学习4. 动手实验多模态模型第一步尝试Swift框架使用数据验证 5. 总结 前言 2024快结束啦&#xff0c;半年抽空学了学多模态还挺好玩的&#xff0c;学习和踩坑记录记一下&…

CAT3D: Create Anything in 3D with Multi-View Diffusion Models 论文解读

24年5月的论文&#xff0c;上一版就是ReconFusion 目录 一、概述 二、相关工作 1、2D先验 2、相机条件下的2D先验 3、多视角先验 4、视频先验 5、前馈方法 三、Method 1、多视角扩散模型 2、新视角生成 3、3D重建 一、概述 该论文提出一种CAT3D方法&#xff0c;实现…

Python中构建终端应用界面利器——Blessed模块

在现代开发中&#xff0c;命令行应用已经不再仅仅是一个简单的文本输入输出工具。随着需求的复杂化和用户体验的重视&#xff0c;终端界面也逐渐成为一个不可忽视的设计环节。 如果你曾经尝试过开发终端UI&#xff0c;可能对传统的 print() 或者 input() 函数感到不满足&#…

5.若依的角色权限控制

RBAC 基于角色的访问控制&#xff0c;通过角色来分配和管理用户的菜单权限。 修改课程管理的菜单到主类目下 新建角色并分配菜单 新建用户并分配角色 添加一个根菜单&#xff0c;父级为主类目

flutter插件开发-ios

flutter插件开发是一个重要的技能&#xff0c;拓展flutter与原生的通信&#xff0c;将一些公用的东西封装&#xff0c;给不同的项目使用。 阅读前置&#xff1a; flutter基本通道调用 objective-c基础语法 ios项目基础知识 目录 1、创建一个插件项目2、项目结构3、编写原生代码…

手机租赁平台开发全攻略打造高效便捷的租赁服务系统

内容概要 手机租赁平台开发&#xff0c;简单说就是让用户能轻松租赁各类手机的高效系统。这一平台不仅帮助那些想要临时使用高端手机的人们节省了不少资金&#xff0c;还为商家开辟了新的收入渠道。随着智能手机的普及&#xff0c;很多人并不需要长期拥有一部手机&#xff0c;…

【从零开始入门unity游戏开发之——C#篇34】C#匿名函数(delegate )和Lambda表达式

文章目录 一、匿名函数&#xff08;delegate &#xff09;1、什么是匿名函数&#xff1f;2、匿名函数的基本语法2.1 语法2.2 **没有参数的匿名函数&#xff1a;**2.3 **有参数的匿名函数&#xff1a;**2.4 **有返回值的匿名函数&#xff1a;** 3、匿名函数的使用示例3.1 作为参…

echarts没有map地图解决方案

在echarts4.9以后的版本中移除了map地图 使用命令npm install echarts --save它会下载最新版本 的echarts 所有我们要下载回echarts4.9版本中 如果已经下载了最新的可以卸载 // 卸载echarts运行&#xff1a; npm uninstall echarts然后再去下载4.9版本 // 安装4.9版本的ech…

WebP Vs. PNG:哪种图像格式适合您的网站?

图像对任何网站都至关重要,可以增强视觉吸引力和用户体验。但是,图像也会显着影响网站的加载时间,因此必须针对 Web 使用对其进行优化。一种方法是使用正确的图像格式。

【Git】—— 代码版本控制工具git的安装及基本使用

目录 一、Git的核心作用 二、安装Git 三、本地仓库命令 1、初始化 2、查看文件状态 3、将文件添加到暂存区 4、将文件提交到本地仓库 5、查看提交日志 6、将暂存区文件取消暂存 7、回溯到指定版本 四、忽略文件 一、Git的核心作用 远程备份&#xff1a;将代码备份到…

sentinel-请求限流、线程隔离、本地回调、熔断

请求限流&#xff1a;控制QPS来达到限流的目的 线程隔离&#xff1a;控制线程数量来达到限流的目录 本地回调&#xff1a;当线程被限流、隔离、熔断之后、就不会发起远程调用、而是使用本地已经准备好的回调去提醒用户 熔断&#xff1a;熔断也叫断路器&#xff0c;当失败、或者…

阿里云人工智能ACA(七)——计算机视觉基础

一、自然语言处理基本介绍 1. 自然语言处理的定义 1-1 自然语言 人类使用的在社会生活中自然形成的语言 1-2 自然语言处理 目标是让计算机能够理解、解析、生成和处理人类的自然语言 包含自然语言理解和自然语言生成两部分组成 2. 自然语言处理的发展趋势 3.自然语言处理…

细说STM32F407单片机通过IIC读写EEPROM 24C02

目录 一、操作说明 二、工程配置 1、时钟、DEBUG、GPIO、USART6、NVIC、Code Generator 2、 IIC2 &#xff08;1&#xff09;Master Features组&#xff0c;主设备参数 &#xff08;2&#xff09;Slave Features组&#xff0c;从设备参数 三、软件设计 1、KELED 2、E…

redis开发与运维-redis04-redis客户端Jedis与连接池及客户端异常模拟

文章目录 【README】【1】redis客户端通信协议【2】java客户端Jedis连接redis集群【2.1】Jedis基本用法【2.2】Jedis操作5种数据类型代码实践【2.3】Jedis使用序列化api操作【2.3.1】操作Jedis字节数组api代码实践 【3】Jedis连接池【3.1】Jedis连接池JedisPool代码实践【3.1.1…

KaiOS 4.0 | DataCall and setupData implemention

相关文档 1、KaiOS 3.1 系统介绍 KaiOS 系统框架和应用结构(APP界面逻辑)文章浏览阅读842次,点赞17次,收藏5次。对于Java开发者而言,理解JS的逻辑调用是有点困难的。而KaiOS webapp开发又不同于现代的web开发,更像chrome浏览器内嵌模式。在这里梳理一下kaios平台web应用…

正则化强度的倒数C——让模型学习更准确

引言 嘿&#xff0c;小朋友们&#xff0c;今天我们要学习一个叫做正则化强度倒数C的概念。这听起来可能有点复杂&#xff0c;但它其实是一种帮助计算机学习的方法。想象一下&#xff0c;我们教计算机识别动物&#xff0c;我们希望它既能识别出猫&#xff0c;也能识别出狗&…