Redisson 集成SpringBoot 详解
一、引入依赖
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.5</version></dependency>
redison-spring-boot-starter依赖于与最新版本的spring-boot兼容的redison-spring数据模块。降级redison弹簧数据模块(如有必要),以支持以前的spring Boot版本:
redisson-spring-data module name | Spring Boot version |
---|---|
redisson-spring-data-16 | 1.3.y |
redisson-spring-data-17 | 1.4.y |
redisson-spring-data-18 | 1.5.y |
redisson-spring-data-2x | 2.x.y |
redisson-spring-data-3x | 3.x.y |
二、添加配置文件
使用 common Spring Boot 3.x+ settings:
spring:data:redis:database: host:port:password:ssl: timeout:connectTimeout:clientName:cluster:nodes:sentinel:master:nodes:
使用common Spring Boot up to 2.7.x settings:
spring:redis:database: host:port:password:ssl: timeout:connectTimeout:clientName:cluster:nodes:sentinel:master:nodes:
配置redision属性(application.yaml):
spring:redis:redisson: config: |clusterServersConfig:idleConnectionTimeout: 10000connectTimeout: 10000timeout: 3000retryAttempts: 3retryInterval: 1500failedSlaveReconnectionInterval: 3000failedSlaveCheckInterval: 60000password: nullsubscriptionsPerConnection: 5clientName: nullloadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}subscriptionConnectionMinimumIdleSize: 1subscriptionConnectionPoolSize: 50slaveConnectionMinimumIdleSize: 24slaveConnectionPoolSize: 64masterConnectionMinimumIdleSize: 24masterConnectionPoolSize: 64readMode: "SLAVE"subscriptionMode: "SLAVE"nodeAddresses:- "redis://127.0.0.1:7004"- "redis://127.0.0.1:7001"- "redis://127.0.0.1:7000"scanInterval: 1000pingConnectionInterval: 0keepAlive: falsetcpNoDelay: falsethreads: 16nettyThreads: 32codec: !<org.redisson.codec.Kryo5Codec> {}transportMode: "NIO"
三、使用 RedissonClient
一切就绪后,除了常用的 StringRedisTemplate
外,我们还可以注入如下由 Redisson 提供的 Bean:
RedissonClient
RedissonRxClient
(响应式)RedissonReactiveClient
(响应式)RedisTemplate
ReactiveRedisTemplate
(响应式)
四、接下来,我们使用 RedissonClient
来实现一个分布式锁,以进行测试:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;import org.junit.jupiter.api.Test;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {static final Logger logger = LoggerFactory.getLogger(DemoApplicationTests.class);// 注入 RedissonClient@AutowiredRedissonClient redissonClient;// 计数器private int count;@Testpublic void test() throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(1000);for (int i = 0; i < 1000; i++) {new Thread(() -> {// 每个线程都创建自己的锁对象// 这是基于 Redis 实现的分布式锁Lock lock = this.redissonClient.getLock("counterLock");try {// 上锁lock.lock();// 计数器自增 1this.count = this.count + 1;} finally {// 释放锁lock.unlock();}countDownLatch.countDown();}).start();}countDownLatch.await();logger.info("count = {}", this.count);}
如上。我们在测试类中注入了 RedissonClient
Bean,并且定义了一个 count
属性。在测试方法中,启动 1000 个线程对 count
属性进行 +1
操作。其中,每个线程都通过 RedissonClient
获取分布式锁来控制对变量的并发修改。
运行测试,输出的日志如下:
INFO 4840 --- [ main] c.s.demo.test.DemoApplicationTests : count = 1000
如你所见,最后的结果是 1000,分布式锁生效。
五、 复杂多维对象结构和对象引用的支持
Redisson突破了Redis数据结构维度的限制,通过一个特殊引用对象的帮助,Redisson允许以任意的组合方式构建多维度的复杂对象结构,实现了对象之间的类似传统数据库里的关联关系。使用范例如下:
RMap<RSet<RList>, RList<RMap>> map = redisson.getMap("myMap");
RSet<RList> set = redisson.getSet("mySet");
RList<RMap> list = redisson.getList("myList");map.put(set, list);
// 在特殊引用对象的帮助下,我们甚至可以构建一个循环引用,这是通过普通序列化方式实现不了的。
set.add(list);
list.add(map);
可能您已经注意到了,在map包含的元素发生改变以后,我们无需再次“保存/持久”这些对象。因为map对象所记录的并不是序列化以后的值,而是元素对象的引用。这让Redisson提供的对象在使用方法上,与普通Java对象的使用方法一致。从而让Redis成为内存的一部分,而不仅仅是一个储存空间。
以上范例中,一共创建了三个Redis数据结构:一个Redis HASH,一个Redis SET和一个Redis LIST。
六、 命令的批量执行
多个连续命令可以通过RBatch对象在一次网络会话请求里合并发送,这样省去了产生多个请求消耗的时间和资源。这在Redis中叫做管道。
用户可以通过以下方式调整通过管道方式发送命令的方式:
BatchOptions options = BatchOptions.defaults()
// 指定执行模式
//
// ExecutionMode.REDIS_READ_ATOMIC - 所有命令缓存在Redis节点中,以原子性事务的方式执行。
//
// ExecutionMode.REDIS_WRITE_ATOMIC - 所有命令缓存在Redis节点中,以原子性事务的方式执行。
//
// ExecutionMode.IN_MEMORY - 所有命令缓存在Redisson本机内存中统一发送,但逐一执行(非事务)。默认模式。
//
// ExecutionMode.IN_MEMORY_ATOMIC - 所有命令缓存在Redisson本机内存中统一发送,并以原子性事务的方式执行。
//
.executionMode(ExecutionMode.IN_MEMORY)// 告知Redis不用返回结果(可以减少网络用量)
.skipResult()// 将写入操作同步到从节点
// 同步到2个从节点,等待时间为1秒钟
.syncSlaves(2, 1, TimeUnit.SECONDS)// 处理结果超时为2秒钟
.responseTimeout(2, TimeUnit.SECONDS)// 命令重试等待间隔时间为2秒钟
.retryInterval(2, TimeUnit.SECONDS);// 命令重试次数。仅适用于未发送成功的命令
.retryAttempts(4);
使用方式如下:
RBatch batch = redisson.createBatch();
batch.getMap("test").fastPutAsync("1", "2");
batch.getMap("test").fastPutAsync("2", "3");
batch.getMap("test").putAsync("2", "5");
batch.getAtomicLongAsync("counter").incrementAndGetAsync();
batch.getAtomicLongAsync("counter").incrementAndGetAsync();BatchResult res = batch.execute();
// 或者
Future<BatchResult> asyncRes = batch.executeAsync();
List<?> response = res.getResponses();
res.getSyncedSlaves();
在集群模式下,所有的命令会按各个槽所在的节点,筛选分配到各个节点并同时发送。每个节点返回的结果将会汇总到最终的结果列表里。
七、Redisson事务
Redisson为RMap、RMapCache、RLocalCachedMap、RSet、RSetCache和RBucket这样的对象提供了具有ACID属性的事务功能。Redisson事务通过分布式锁保证了连续写入的原子性,同时在内部通过操作指令队列实现了Redis原本没有的提交与滚回功能。当提交与滚回遇到问题的时候,将通过org.redisson.transaction.TransactionException告知用户。
目前支持的环境如下: SINGLE, MASTER/SLAVE, SENTINEL, ELASTICACHE REPLICATED, AZURE CACHE, RLEC。
Redisson事务支持的事务隔离等级为: READ_COMMITTED,即仅读取提交后的结果。
另见 Spring事务管理器 和本章 XA事务(XA Transactions)。
以下选项可以用来配置事务属性:
TransactionOptions options = TransactionOptions.defaults()
// 设置参与本次事务的主节点与其从节点同步的超时时间。
// 默认值是5秒。
.syncSlavesTimeout(5, TimeUnit.SECONDS)// 处理结果超时。
// 默认值是3秒。
.responseTimeout(3, TimeUnit.SECONDS)// 命令重试等待间隔时间。仅适用于未发送成功的命令。
// 默认值是1.5秒。
.retryInterval(2, TimeUnit.SECONDS)// 命令重试次数。仅适用于未发送成功的命令。
// 默认值是3次。
.retryAttempts(3)// 事务超时时间。如果规定时间内没有提交该事务则自动滚回。
// 默认值是5秒。
.timeout(5, TimeUnit.SECONDS);
代码范例:
RTransaction transaction = redisson.createTransaction(TransactionOptions.defaults());RMap<String, String> map = transaction.getMap("myMap");
map.put("1", "2");
String value = map.get("3");
RSet<String> set = transaction.getSet("mySet")
set.add(value);try {transaction.commit();
} catch(TransactionException e) {transaction.rollback();
}
八、XA事务(XA Transactions)
Redisson提供了XAResource标准的实现。该实现可用于JTA事务中。
另见本章Redisson事务和Spring事务管理器。
该功能仅适用于Redisson PRO版本
代码范例:
// Transaction对象可以从所有兼容JTA接口的事务管理器中获取。
Transaction globalTransaction = transactionManager.getTransaction();RXAResource xaResource = redisson.getXAResource();
globalTransaction.enlistResource(xaResource);RTransaction transaction = xaResource.getTransaction();
RBucket<String> bucket = transaction.getBucket("myBucket");
bucket.set("simple");
RMap<String, String> map = transaction.getMap("myMap");
map.put("myKey", "myValue");transactionManager.commit();
相关文章:
Redisson 集成SpringBoot 详解
一、引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.5</version></dependency> redison-spring-boot-starter依赖于与最新版本的spring-boot兼容…...
C# 下载模板文件 Excel
后端代码 [HttpGet("DownloadExcel")]public async Task<dynamic> DownloadExcel(string tmplName){var _fileName "导入表模板.xlsx";var filePath "Files\DownLoad\";var NewFile Path.Combine(filePath, tmplName);var stream new…...

如何做好sop流程图?sop流程图用什么软件做?
5.如何做好sop流程图?sop流程图用什么软件做? 建立标准作业程序sop已经成为企业进步和发展的必经之路,不过,很多刚刚开始着手搭建sop的企业并不知道要如何操作,对于如何做sop流程图、用什么软件做sop流程图等问题充满…...

JAVA编程题-求矩阵螺旋值
螺旋类 package entity; /*** 打印数组螺旋值类*/ public class Spiral { // 数组行private int row; // 数组列private int col; // 行列数private int size; // 当前行索引private int rowIndex; // 当前列索引private int colIndex; // 行开始索引private int rowStart; //…...

Python--入门
标识符 标识符由字母,数字,下划线_组成 第一个字符不能是数字,必须是字母或下划线 标识符区分大小写 关键字 关键字即保留字,定义标识符时不能使用关键字,python中的关键字如下图 注释 python中的单行注释用 # 多行注…...

STM32复习笔记(二):GPIO
目录 (一)Demo流程 (二)工程配置 (三)代码部分 (四)外部中断(EXTI) (一)Demo流程 首先,板子上有4个按键,…...

POJ 3264 Balanced Lineup 线段树 / 平方分割
一、题目大意 给出一个长度为 n(n<50000) 数组 arr,进行Q次查询(Q<200000),每次查询的内容为数组arr在 [L , R] 的切片的极差(最大元素 - 最小元素) 二、解题思路 1、线段树 区间极差…...

element-plus自动引入组件报错,例如collapse、loading
element-plus自动引入组件,例如collapse、loading,使用时报错,报错信息如下图所示: 解决办法:vite-config.ts改变vue的引入顺序,将vue放在第一个...

ChainForge:衡量Prompt性能和模型稳健性的GUI工具包
ChainForge是一个用于构建评估逻辑来衡量模型选择,提示模板和执行生成过程的GUI工具包。ChainForge可以安装在本地,也可以从chrome浏览器运行。 ChainForge可以通过聊天节点对多个对话可以使用不同的llm并行运行。可以对聊天消息进行模板化,并…...
队列--二叉树层序遍历
/*1/ \2 3/\ /\4 5 6 7利用LinkedListQueue1. 头 [1] 尾12.头 [2 3] 尾1 23.头 [3 4 5] 尾1 24.头 [4 5 6 7] 尾1 2 35.头 [] 尾1 2 3 4 5 6 7*/ 代码: class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List&l…...
Ceph入门到精通-Linux内核网络参数优化小结
tcp建连优化 1 tcp建连,降低客户端超时时间 net.ipv4.tcp_syn_retries 6 2 tcp建连,服务端避免syn攻击 netstat -s | grep "SYNs to LISTEN" 1192450 SYNs to LISTEN sockets dropped 可以考虑增大syn队列 net.ipv4.tcp_max_syn_backlo…...
AWK语言第二版 2.6个人库 2.7小结
2.6 个人库 Awk提供了适量的内置函数库,如 length、sub、substr、printf 等其他十来个;在A.2.1节的参考手册中都有列出。你可以自己创建更多函数,以便有需要时引入到Awk程序中。比如内置库函数 sub 和 gsub 都只能返回替换的次数,…...

8年经验之谈 —— Web ui自动化测试框架总结!
实施过了web系统的UI自动化,回顾梳理下,想到什么写什么,随时补充。 首先,自动化测试不是手动测试的替代品,是比较好的补充,而且不是占大比重的补充。 70%的测试工作集中在底层接口测试和单元测试࿰…...

Kafka在企业级应用中的实践
前言 前面说了很多Kafka的性能优点,有些童鞋要说了,这Kafka在企业开发或者企业级应用中要怎么用呢?今天咱们就来简单探究一下。 1、 使用 Kafka 进行消息的异步处理 Kafka 提供了一个可靠的消息传递机制,使得企业能够将不同组件…...

使用企业订货系统后的效果|软件定制开发|APP小程序搭建
使用企业订货系统后的效果|软件定制开发|APP小程序搭建 企业订货系统是一种高效的采购管理系统,它可以帮助企业更好地管理采购流程,降低采购成本,提高采购效率。 可以帮助企业提高销售效率和降低成本的软件工具。使用该系统后,企业…...
STL关联式容器set,multiset,pair,map
set容器是一个集合容器。包含元素是唯一的。集合元素按照一点顺序排列,元素插入过程是顺序插入,所有不能插入指定位置。 set采用红黑树变体的数据结构实现。红黑树属于平衡二叉树。再插入和删除上比vector快。 set不能直接存取元素(不能用a…...

MFC文本输出学习
void CTxttstView::OnDraw(CDC* pDC) {CTxttstDoc* pDoc GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCString str1;pDC->SetBkColor(RGB(0,0,0));pDC->TextOut(50, 50, "一段文字");pDC->SetBkColor(RGB(255,255,255))…...

Python 数据分析与挖掘(一)
Python 数据分析与挖掘(数据探索) 数据探索 1.1 需要掌握的工具(库) 1.1.1 Nump库 Numpy 提供多维数组对象和各种派生对象(类矩阵),利用应用程序接口可以实现大量且繁琐的数据运算。可以构建…...

【问题证明】矩阵方程化为特征值方程求得的特征值为什么是全部特征值?不会丢解吗?
问题 这个问题困扰了我好久,一直感觉如果有其他的特征值没法证伪,不过一直存在思想的层面,没有实际解决,今天突然想到动笔来解决,遂得解,证明如下。 证明 总结 这个证明看似证明过后很直观,但…...

虹科干货 | 不是吧,Redis Enterprise也能当向量数据库来用?
什么是向量相似性搜索啊? 例如,你需要搜索一棵发财树的图片,如果用传统数据库来检索,你大概率会在茫茫树丛中错失心仪的发财树。但是,向量相似性搜索能用向量来表示所有树的特征,这样就能够通过计算向量之间…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...