Redisson 总结

1. 基础使用

1.1 引入依赖

<dependencies><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId></dependency>
</dependencies>

包含的依赖如下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.2 配置文件

其实默认主机就是 127.0.0.1,默认端口是 6379,一致的话可以不用配置

spring:data:redis:host: 127.0.0.1password: redis

1.3 测试类

import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RBucket<String> bucket = redissonClient.getBucket("test");bucket.set("hello");}@GetMapping("/get")public String get() {RBucket<String> bucket = redissonClient.getBucket("test");return bucket.get();}
}

1.4 测试

访问 /test 接口,利用 Redis 管理工具可以看到数据已经添加了进来

在访问 /get 接口,成功获取到数据

2. 设置序列化

上面可以看到在 Redis 管理工具中查看数据是一串字符,并不直观,可以自定义数据序列化

2.1 配置类

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RedissonConfig {@Beanpublic RedissonClient redissonClient() {Config config = new Config();// 单机模式SingleServerConfig singleServerConfig = config.useSingleServer();singleServerConfig.setAddress("redis://127.0.0.1:6379");singleServerConfig.setPassword("redis");// JSON序列化config.setCodec(new JsonJacksonCodec());return Redisson.create(config);}
}

这里已经配置了主机等相关信息,因此配置文件里的配置可以去除,或者这里直接取配置文件的值,具体根据情况选择,其他的序列化类如下

编码类名称说明
org.redisson.codec.JsonJacksonCodecJackson JSON 编码
org.redisson.codec.AvroJacksonCodecAvro 一种二进制的 JSON 编码
org.redisson.codec.SmileJacksonCodecSmile一种 二进制的 JSON 编码
org.redisson.codec.CborJacksonCodecCBOR 一种二进制的 JSON 编码
org.redisson.codec.MsgPackJacksonCodecMsgPack 一种 二进制的 JSON 编码
org.redisson.codec.IonJacksonCodecAmazon Ion 亚马逊的 Ion 编码,格式与 JSON 类似
org.redisson.codec.KryoCodecKryo 二进制对象序列化编码
org.redisson.codec.SerializationCodecJDK 序列化编码
org.redisson.codec.FstCodecFST 10 倍于 JDK 序列化性能而且 100% 兼容的编码
org.redisson.codec.LZ4CodecLZ4 压缩型序列化对象编码
org.redisson.codec.SnappyCodecSnappy 另一个压缩型序列化对象编码
org.redisson.client.codec.JsonJacksonMapCodec基于 Jackson 的映射类使用的编码,可用于避免序列化类的信息,以及用于解决使用byte[] 遇到的问题
org.redisson.client.codec.StringCodec纯字符串编码(无转换)
org.redisson.client.codec.LongCodec纯整长型数字编码(无转换)
org.redisson.client.codec.ByteArrayCodec字节数组编码
org.redisson.codec.CompositeCodec用来组合多种不同编码在一起

2.2 测试

访问 /test 接口,再查看数据可以看到已经序列化成 JSON 格式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. 基础数据结构使用

3.1 String

其实上面的示例用的就是字符串操作,通过 RBucket 对象来操作字符串数据结构

创建一个实体类

import lombok.Builder;
import lombok.Data;import java.io.Serial;
import java.io.Serializable;@Data
@Builder
public class Article implements Serializable {@Serialprivate static final long serialVersionUID = -8862397425409851538L;private String title;private String content;
}

存储对象,简单示例如下:

import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RBucket<Object> bucket = redissonClient.getBucket("test");bucket.set(Article.builder().title("demo").content("test redisson").build());}
}

数据如下:

3.2 Hash

通过 RMap 对象来操作哈希数据结构,简单示例如下:

import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RMap<String, Article> rMap = redissonClient.getMap("test");rMap.put("k1", Article.builder().title("demo").content("test redisson").build());}
}

数据如下:

3.3 List

3.3.1 无序

通过 RList 对象来操作列表数据结构,简单示例如下:

import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RList<Article> rList = redissonClient.getList("test");rList.add(Article.builder().title("demo").content("test redisson").build());rList.add(Article.builder().title("demo").content("test redisson").build());}
}

数据如下:

3.3.2 有序

通过 RSortedSet 对象来操作有序集合数据结构

改造一下实体类,实现 Comparable 接口

import lombok.Data;import java.io.Serial;
import java.io.Serializable;@Data
public class Article implements Serializable, Comparable<Article> {@Serialprivate static final long serialVersionUID = -8862397425409851538L;private Long id;private String title;private String content;@Overridepublic int compareTo(Article article) {return this.getId().compareTo(article.getId());}
}

简单示例如下:

import org.redisson.api.RSortedSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RSortedSet<Article> rSortedSet = redissonClient.getSortedSet("test");Article article1 = new Article();article1.setId(22L);article1.setTitle("demo");article1.setContent("test redisson");rSortedSet.add(article1);Article article2 = new Article();article2.setId(11L);article2.setTitle("demo");article2.setContent("test redisson");rSortedSet.add(article2);}
}

数据如下,可以看到数据根据 id 排序

3.4 Set

通过 RSet 对象来操作集合数据结构,简单示例如下:

import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RSet<Article> rSet = redissonClient.getSet("test");rSet.add(Article.builder().title("demo").content("test redisson").build());rSet.add(Article.builder().title("demo").content("test redisson").build());}
}

数据如下,可以看到重复数据被去除了

3.5 Zset

通过 RScoredSortedSet 来操作带分数的有序集合数据结构,简单示例如下:

import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RScoredSortedSet<String> rScoredSortedSet = redissonClient.getScoredSortedSet("test");rScoredSortedSet.add(600.1, "test1");rScoredSortedSet.add(500.3, "test2");rScoredSortedSet.add(900.3, "test3");rScoredSortedSet.add(200.9, "test1");}
}

数据如下,可以看到根据分数来排序,并且重复数据被排除了

4. 布隆过滤器

可以用于检索一个元素是否在一个集合中

import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.time.Duration;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RBloomFilter<String> rBloomFilter = redissonClient.getBloomFilter("test");// 初始化预期插入的数据量为10000和期望误差率为0.01rBloomFilter.tryInit(10000, 0.01);// 插入部分数据rBloomFilter.add("100");rBloomFilter.add("200");rBloomFilter.add("300");// 设置过期时间rBloomFilter.expire(Duration.ofSeconds(30));// 判断是否存在System.out.println(rBloomFilter.contains("300")); // trueSystem.out.println(rBloomFilter.contains("200")); // trueSystem.out.println(rBloomFilter.contains("999")); // false}
}

5. 分布式自增 ID

参考代码如下:

import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RAtomicLong rAtomicLong = redissonClient.getAtomicLong("test");System.out.println(rAtomicLong.incrementAndGet());}
}

6. 分布式锁

6.1 未加锁情况

模拟一个库存扣减操作

import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RBucket<Integer> bucket = redissonClient.getBucket("num");Integer num = bucket.get();if (num > 0) {System.out.println("扣减库存, 当前库存: " + --num);bucket.set(num);} else {System.out.println("库存不足");}}
}

使用 Jemter 模拟并发场景

点击运行后可以看到明显出现了并发问题

6.2 加锁情况

修改下库存扣减代码

import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RLock rLock = redissonClient.getLock("test");try {rLock.lock();RBucket<Integer> bucket = redissonClient.getBucket("num");Integer num = bucket.get();if (num > 0) {System.out.println("扣减库存, 当前库存: " + --num);bucket.set(num);} else {System.out.println("库存不足");}} finally {rLock.unlock();}}
}

再次模拟并发请求,可以看到问题已经解决

6.3 加锁操作耗时长

当加锁操作耗时较长时,如果多个请求进来,其他的请求会一直堵塞,可以使用 tryLock 来尝试获取锁,获取不到先返回响应

import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {private final RedissonClient redissonClient;@Autowiredpublic DemoController(RedissonClient redissonClient) {this.redissonClient = redissonClient;}@GetMapping("/test")public void test() {RLock rLock = redissonClient.getLock("test");try {if (rLock.tryLock()) {RBucket<Integer> bucket = redissonClient.getBucket("num");Integer num = bucket.get();Thread.sleep(5000);if (num > 0) {System.out.println("扣减库存, 当前库存: " + --num);bucket.set(num);} else {System.out.println("库存不足");}} else {System.out.println("请稍后再试");}} catch (InterruptedException e) {System.out.println(e.getMessage());Thread.currentThread().interrupt();} finally {// 是否是锁定状态且是当前执行线程的锁if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {rLock.unlock();}}}
}

模拟并发请求,这里将时间设置长一点,可以看到获取到锁的请求则去进行库存扣减,获取不到先返回响应

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/430790.html

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

相关文章

MCU自动测量单元采集振弦式应变计测值的过程

振弦式应变计是一种广泛应用于土木工程、地质勘探等领域的高精度传感器&#xff0c;用于测量结构的应变变化。近年来&#xff0c;随着微控制器单元(MCU)的发展&#xff0c;自动化测量技术得到了极大的提升&#xff0c;使得振弦式应变计的测值采集更加高效和精确。本文将详细介绍…

vue-router路由(重定向,嵌套,动态路由匹配,命名,高亮,守卫)

一、前端路由的概念与原理 路由router就是对应关系。分为前端路由和后端路由。 1后端路由 后端路由指的是&#xff1a;请求方式、请求地址与function处理函数之间的对应关系。在node.js中&#xff0c;express理由的基本用法如下&#xff1a; const express require(expres…

IPsec-Vpn

网络括谱图 IPSec-VPN 配置思路 1 配置IP地址 FWA:IP地址的配置 [FW1000-A]interface GigabitEthernet 1/0/0 [FW1000-A-GigabitEthernet1/0/0]ip address 10.1.1.1 24 [FW1000-A]interface GigabitEthernet 1/0/2 [FW1000-A-GigabitEthernet1/0/2]ip address

【编程底层原理】Java常用读写锁的使用和原理

一、引言 在Java的并发世界中&#xff0c;合理地管理对共享资源的访问是至关重要的。读写锁&#xff08;ReadWriteLock&#xff09;正是一种能让多个线程同时读取共享资源&#xff0c;而写入资源时需要独占访问的同步工具。本文将带你了解读写锁的使用方法、原理以及它如何提高…

基于SSM的“银发在线教育云平台”的设计与实现(源码+数据库+文档)

基于SSM的“银发在线教育云平台”的设计与实现&#xff08;源码数据库文档) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 首页页面图 健身养生详情页面 在线课堂界面 …

解决 Prettier ESLint 错误

解决 Prettier ESLint 错误 在 Vue.js 项目中使用 ESLint 和 Prettier 时&#xff0c;你可能会遇到类似以下的错误&#xff1a; frontend\src\views\dashboard\MobileConfigPanel.vue1:25 error Delete ␍ …

ByteTrack多目标跟踪流程图

ByteTrack多目标跟踪流程图 点个赞吧&#xff0c;谢谢。

Linux:文件描述符详解

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 Linux中的所有进程&#xff0c;都拥有自己的文件描述符(File Descriptor, FD)&#xff0c;它是操作系统在管理进程和文件时的一种抽象概念。每个文件描述符由一个非负整…

Error when custom data is added to Azure OpenAI Service Deployment

题意&#xff1a;在向 Azure OpenAI 服务部署添加自定义数据时出现错误。 问题背景&#xff1a; I receive the following error when adding my custom data which is a .txt file (it doesnt matter whether I add it via Azure Cognitive Search, Azure Blob Storage, or F…

网络安全等级保护 | 规范企业网络系统安全使用 | 天锐股份助力等保制度落地

在当今数字化高速发展的时代&#xff0c;网络安全对于企业的重要性日益凸显。而近年来&#xff0c;数据泄露、网络攻击等安全事件频发&#xff0c;给企业和个人带来了前所未有的挑战。在这一背景下&#xff0c;网络安全等级保护制度&#xff08;简称“等保”&#xff09;作为国…

安卓13删除下拉栏中的设置按钮 android13删除设置按钮

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 顶部导航栏下拉可以看到,底部这里有个设置按钮,点击可以进入设备的设置页面,这里我们将更改为删除,不同用户通过这个地方进入设置。也就是下面这个按钮。 2.问题分析…

Java面试题大全(全网最全,持续更新)中级(3)

1. 集合框架 1.1. ConcurrentHashMap 和 HashMap 有什么区别&#xff1f; HashMap&#xff1a;线程不安全&#xff0c;适用于单线程环境。ConcurrentHashMap&#xff1a;线程安全&#xff0c;适用于多线程环境&#xff0c;使用分段锁机制来提高并发性能。 1.2. TreeSet 如何实…

【C++掌中宝】走进C++引用的世界:从基础到应用

文章目录 引言1. 基础概念2. 引用与指针的区别3. 引用的应用场景3.1 引用作为函数参数3.2 引用作为函数返回值3.3 常引用&#xff08;const引用&#xff09;的使用3.4 引用与多态 4. C 引用的优缺点5. 引用的注意事项与常见陷阱6. 总结结语 引言 C 引用是编写高效、简洁代码的…

新品亮相|美格智能SLM530/SLM530P智能模组,助力金融新零售智慧升级

随着金融支付产业数字化与智能化不断推进&#xff0c;泛支付场景一体化解决方案成为行业发展的新趋势&#xff0c;从手持POS机到智能收款机&#xff0c;金融支付领域需要更快速、更精准、更安全的解决方案&#xff0c;加快推进数字化升级进程。 近期&#xff0c;美格智能正式发…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-18

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-18 1. The Application of Large Language Models in Primary Healthcare Services and the Challenges W YAN, J HU, H ZENG, M LIU, W LIANG - Chinese General Practice, 2024 人工智能大语言模型在基层医疗…

基于深度学习的文本情感原因提取研究综述——论文阅读

前言 既然要学习情感分析&#xff0c;那么肯定还要了解情感原因对抽取的发展历程&#xff0c;所以我又搜了一篇研究综述&#xff0c;虽然是2023年发表的&#xff0c;但是里面提及到的历程仅停留到2022年。这篇综述发布在TASLP期刊&#xff0c;是音频、声学、语言信号处理的顶级…

静态路由和默认路由(实验)

目录 一、实验设备和环境 1、实验设备 2、实验环境 &#xff08;1&#xff09;实验拓扑图 &#xff08;2&#xff09;实验命令列表 二、实验记录 1、直连路由与路由表查看 步骤1:建立物理连接并运行超级终端。 步骤2:在路由器上查看路由表。 2、静态路由配置 步骤1:配…

哈希表与离散化

一、字符串哈希 1. 什么是哈希 哈希算法是&#xff1a;通过哈希函数将字符串、较大的数等转换为能够用变量表示的或者是直接作为数组下标的数&#xff0c;通过哈希算法转换到的值&#xff0c;称之为哈希值。哈希值可以实现快速查找和匹配。 比如&#xff1a;用数组下标计数法&…

QT widgets 窗口缩放,自适应窗口大小进行布局

1. 窗口布局 2. 尺寸策略&#xff1a;扩展 Fixed (固定): 行为&#xff1a;控件的大小是固定的&#xff0c;不会随着窗口大小的变化而改变。它的大小由控件的 sizeHint() 返回的值决定。 适用场景&#xff1a;当你希望控件的大小保持不变&#xff0c;不随布局调整时使用&#x…

Windows下利用MSYS2和VS的nmake编译nginx源码

目录 一、使用说明 二、安装软件 2.1 下载依赖库 2.3 下载并安装 StrawberryPerl 2.4 下载并安装 MSYS 2 2.5 nginx源代码下载 三、编译配置 3.1 设置NGX_MSVC_VER 3.2 配置 Makefile 3.3 编译代码 3.4 整理Nginx发布环境 四、错误处理 一、使用说明 本文章主要记…