SpringBoot中使用Redis-Lettuce

news/2024/9/18 10:17:28/ 标签: spring boot, redis, 后端, Java

SpringBoot中使用Redis-Lettuce

  • 配置pom
  • 在`application.properties`配置`Redis`参数
  • 协议参数设置
  • 序列化参数设置
  • 实现工具`Redis`操作工具类
  • 单条数据测试
  • 批量测试

SpringBoot中一般直接引用spring-boot-starter-data-redis这个starter来使用Redis,其中具体实现方式有两种方式
1、Lettuce
2、Jedis

配置pom

注意,这里我们使用lettuce,需要用到连接池信息,这里使用的是apachecommons-pool2

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.3</version><relativePath/></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><properties><java.version>21</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-core</artifactId><version>3.6.8</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.11.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

application.properties配置Redis参数

具体参数信息参考org.springframework.boot.autoconfigure.data.redis.RedisProperties,不同版本有些微差别

spring.application.name=demo
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
spring.data.redis.password=XXXX
spring.data.redis.clientType=LETTUCE
spring.data.redis.lettuce.pool.enabled=true
spring.data.redis.lettuce.pool.min-idle=2
spring.data.redis.lettuce.pool.max-idle=20
spring.data.redis.lettuce.pool.max-active=20
spring.data.redis.lettuce.pool.max-wait=5000

协议参数设置

这里可以设置一些个性化的参数,其中一个就是协议版本,如果使用的Redis版本低于6.0,需要使用ProtocolVersion.RESP2

@Configuration
public class CustomLettuceClientConfigurationBuilderCustomizer implements LettuceClientConfigurationBuilderCustomizer {private static final int TIMEOUT = 30;private static final SocketOptions socketOptions = SocketOptions.builder().keepAlive(SocketOptions.KeepAliveOptions.builder().enable().idle(Duration.ofSeconds(TIMEOUT)).interval(Duration.ofSeconds(TIMEOUT / 3)).count(3).build()).tcpUserTimeout(SocketOptions.TcpUserTimeoutOptions.builder().enable().tcpUserTimeout(Duration.ofSeconds(TIMEOUT)).build()).build();@Overridepublic void customize(LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigurationBuilder) {// redis 6.0以前版本需要使用ProtocolVersion.RESP2clientConfigurationBuilder.clientOptions(ClientOptions.builder().socketOptions(socketOptions).protocolVersion(ProtocolVersion.RESP3).build());}
}

序列化参数设置

1、这里直接使用的StringRedisTemplate,要求全部是字符串,序列化的工作交给调用方自己处理,
2、如果要扩展RedisTemplate<K, V>,实现自己的特殊逻辑,这里就要设置key、value的序列化方式

@Configuration
public class RedisConfig {@Beanpublic StringRedisTemplate stringRedisTemplate(LettuceConnectionFactory factory) {// 验证是否可用factory.validateConnection();// 其他参数StringRedisTemplate template = new StringRedisTemplate();template.setConnectionFactory(factory);return template;}
}

实现工具Redis操作工具类

public interface RedisService {/*** 写入缓存** @param key      缓存key* @param value    缓存value* @param timeout  超时时间* @param timeUnit 时间单位* @return*/void set(String key, String value, long timeout, TimeUnit timeUnit);/*** 获取缓存值** @param key 缓存key* @return*/String get(String key);
}@Service
public class RedisServiceImpl implements RedisService {@Autowiredprivate StringRedisTemplate redisTemplate;@Overridepublic void set(String key, String value, long timeout, TimeUnit timeUnit) {redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}@Overridepublic String get(String key) {return redisTemplate.opsForValue().get(key);}
}

单条数据测试

@SpringBootTest
public class DemoApplicationTests {@Autowiredprivate RedisService redisService;@Testpublic void testSetGet() {String key = "hello";String value = "测试数据";redisService.set(key, value, 10, TimeUnit.SECONDS);Assertions.assertEquals(value, redisService.get(key));}
}    

批量测试

这里主要测试一下连接池参数,找到一个合理配置

public class DemoApplicationTests {@Autowiredprivate RedisService redisService;@Testpublic void testPool() {this.testSetGet();ExecutorService executorService = Executors.newFixedThreadPool(10);int total = 10000;for (int i = 0; i < 10; i++) {int calcTotal = testPool(total, executorService);Assertions.assertEquals(calcTotal, total);}executorService.shutdown();executorService.close();}private int testPool(int total, ExecutorService executorService) {long start = System.currentTimeMillis();List<CompletableFuture<Integer>> list = IntStream.rangeClosed(1, total).mapToObj(it -> {return build(it, executorService);}).toList();CompletableFuture.allOf(list.toArray(CompletableFuture[]::new)).join();int calcTotal = list.stream().filter(Objects::nonNull).map(it -> {try {return it.get();} catch (Exception e) {return 0;}}).reduce(0, Integer::sum);long end = System.currentTimeMillis();System.out.println("耗时:" + (end - start) / 1000.0 + "s");return calcTotal;}private CompletableFuture<Integer> build(int it, ExecutorService executorService) {final String key = "test:hello:" + it;final String value = "value-" + it;return CompletableFuture.supplyAsync(() -> {try {redisService.set(key, value, 10, TimeUnit.SECONDS);boolean suc = value.equals(redisService.get(key));// System.out.println("build -> " + it + " -> " + Thread.currentThread().getName());if (!suc) {System.out.println("failed ->" + it);return 0;} else {return 1;}} catch (Exception e) {System.out.println("error ->" + it + ", " + e.getMessage());return 0;}}, executorService);}
} 

http://www.ppmy.cn/news/1521052.html

相关文章

【自动驾驶】控制算法(八)横向控制Ⅰ | 算法与流程

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

聊聊Redis分布式锁的八大坑

前言 在分布式系统中&#xff0c;由于redis分布式锁相对于更简单和高效&#xff0c;成为了分布式锁的首先&#xff0c;被我们用到了很多实际业务场景当中。 但不是说用了redis分布式锁&#xff0c;就可以高枕无忧了&#xff0c;如果没有用好或者用对&#xff0c;也会引来一些…

matlab二维热传导显示有限差分法计算(代码)

% 参数设置 x00; % x起点y00; % y起点Lx 1; % x方向长度 Ly 1; % y方向长度 Nx 100; % x方向网格数 Ny 100; % y方向网格数 dx (Lx-x0) / Nx; % x方向步长 dy (Ly-y0) / Ny; % y方向步长 alpha 0.01; % 热扩散率 dt 0.01; % 时间步长 T 1; % 总时间 nt …

Samba服务

samba 服务 一、简介 Samba 是一种在 Linux 和 Unix 系统上实现 SMB&#xff08;Server Message Block&#xff09;协议的服务&#xff0c;其目的是提供文件和打印服务。它可以让 Windows、Linux 和 Unix 之间实现文件和打印机的共享&#xff0c;并且支持通过 SMB/CIFS 协议进…

海外媒体发稿:排名靠前的Vents杂志网站发布新闻通稿-大舍传媒

海外媒体发稿&#xff1a;排名靠前的Vents杂志网站发布新闻通稿 近日&#xff0c;知名海外媒体Vents杂志网站发布了最新一期新闻通稿&#xff0c;涵盖了音乐、娱乐、新闻等多个领域的热点事件。作为一家自2009年成立以来便致力于为全球读者提供第一手资讯的在线媒体&#xff0…

深入解析Spring Boot中的`@Transactional`注解

一、Transactional注解概述 1.1 什么是Transactional Transactional是Spring框架中用于声明式事务管理的注解。通过在方法或类上添加Transactional注解&#xff0c;Spring会自动将该方法或类中的数据库操作纳入到事务管理中&#xff0c;从而保证这些操作的原子性、一致性、隔…

ES6中try-catch

在ES6&#xff08;ECMAScript 2015&#xff09;中&#xff0c;try-catch 语句的语法和使用方式与在之前的ECMAScript版本中是一样的。try-catch 语句用于处理代码中可能发生的错误&#xff0c;确保程序的健壮性和用户体验。 基本语法 try { // 尝试执行的代码块 // 如果发生…

Chrome 浏览器插件获取网页 window 对象(方案二)

前言 最近有个需求&#xff0c;是在浏览器插件中获取 window 对象下的某个数据&#xff0c;当时觉得很简单&#xff0c;和 document 一样&#xff0c;直接通过嵌入 content_scripts 直接获取&#xff0c;然后使用 sendMessage 发送数据到插件就行了&#xff0c;结果发现不是这…

TCP如何关闭连接(详细版)

关闭连接的⽅式通常有两种&#xff0c;分别是 RST 报⽂关闭和 FIN 报⽂关闭。 如果进程异常退出了&#xff0c;内核就会发送 RST 报⽂来关闭&#xff0c;它可以不⾛四次挥⼿流程&#xff0c;是⼀个暴⼒关闭连接的⽅式。 安全关闭连接的⽅式必须通过四次挥⼿&#xff0c;它…

uniap app跳转小程序

微信开放平台申请账号并认证配置APP的相关配 其中安卓的包名可以通过反编译工具查看链接 https://download.csdn.net/download/u010843503/88725345d打开后 其中md5就是签名&#xff0c;复制后把中间空格取消就行。 微信开放平台绑定小程序 绑定后查看微信小程序的原始id也…

win11+vscode+Flutter 开发环境配置

https://blog.csdn.net/Oven_maizi/article/details/126804404 1 vscode插件 安装 安装红框中的两个 2 flutter sdk 安装 dart sdk 包含在flutter sdk 里面&#xff0c;路径&#xff1a;flutter_windows_3.24.1-stable\flutter\bin\cache\dart-sdk 方式1&#xff1a; 通过…

CSS中表示长度的单位有哪些?有什么区别?

CSS中有px、em和rem三个长度单位。px是固定像素&#xff0c;不随页面大小变化&#xff1b;em和rem是相对长度单位&#xff0c;em相对于父元素&#xff0c;rem相对于根元素&#xff08;html&#xff09;。 在响应式布局中&#xff0c;rem更常用&#xff0c;因为它只有一个参照物…

Ansible与Docker集成:实现容器化运维自动化

Ansible与Docker集成&#xff1a;实现容器化运维自动化 在现代 DevOps 和云原生环境中&#xff0c;Ansible 和 Docker 是两种非常受欢迎的工具。Ansible 专注于配置管理和任务自动化&#xff0c;而 Docker 则通过容器化技术实现应用的轻量级隔离和部署。将 Ansible 和 Docker …

基于udp的socket网络编程

套接字 网络套接字 原始套接字 unix套接字 windows下SOCKET 为整数。 协议家族 套接字种类 协议 udpServer.cc #pragma warning(disable:4996) #include<iostream> #include<string> #include<cstdlib> #include<WinSock2.h>#pragma comment(li…

mac电脑里面的 磁盘分区,容器,宗卷,宗卷组的理解和使用

在mac电脑里面我们一般都是使用宗卷&#xff0c;他和我们常见的pc机器硬盘的分区是有区别的。 对于物理硬盘来说 不管是分区还是宗卷&#xff0c;他们都是逻辑上面的概念。 分区 mac电脑里面的分区 和 pc电脑中的分区差不多&#xff0c; 他们都是针对的物理硬盘&#xff0c;…

Java 方法的特性详解

目录 一、引言 二、方法的重载 &#xff08;一&#xff09;定义与作用 &#xff08;二&#xff09;判断方法相同的标准 三、可变个数形参的方法 &#xff08;一&#xff09;使用场景 &#xff08;二&#xff09;格式与特点 &#xff08;三&#xff09;代码示例 四、方…

【大模型】llama系列模型基础

前言&#xff1a;llama基于transformer架构&#xff0c;与GPT相似&#xff0c;只用了transformer的解码器部分。本文主要是关于llama&#xff0c;llama2和llama3的结构解读。 目录 1. llama1.1 整体结构1.2 RoPE1.3 SwiGLU 激活函数 2. llama22.2 GQA架构2.3 RLHF 3. llama3参考…

ubuntu20.04(wsl2)测试 arcface 人脸识别(计算特征向量)

1. 参考博客和代码、模型仓库&#xff1a; 1.1. 【C随记】collect2: error: ld returned 1 exit status错误分析与解决 1.2. Visual Studio 2022新建 cmake 工程测试 tensorRT 自带样例 sampleOnnxMNIST 1.3.报错&#xff1a;ModuleNotFoundError: No module named ‘ten…

力扣SQL仅数据库(570-579)

570. 至少有5名直接下属的经理 需求&#xff1a; 编写一个解决方案&#xff0c;找出至少有五个直接下属的经理 数据准备&#xff1a; Create table If Not Exists Employee (id int, name varchar(255), department varchar(255), managerId int) Truncate table Employee i…

Mysql梳理1——数据库概述(上)

笔记来源&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 https://www.bilibili.com/video/BV1iq4y1u7vj 目录 11.2 引入 11.2. 1 数据库与数据库管理系统 11.2.2 数据库与数据库管理系统的关系 11.2.…