SpringBoot中使用Redis-Lettuce

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();

    @Override
    public void customize(LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigurationBuilder) {
        // redis 6.0以前版本需要使用ProtocolVersion.RESP2
        clientConfigurationBuilder.clientOptions(ClientOptions.builder()
                .socketOptions(socketOptions)
                .protocolVersion(ProtocolVersion.RESP3)
                .build());

    }
}

序列化参数设置

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

@Configuration
public class RedisConfig {
    @Bean
    public 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 {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void set(String key, String value, long timeout, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    @Override
    public String get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
}

单条数据测试

@SpringBootTest
public class DemoApplicationTests {
    @Autowired
    private RedisService redisService;

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

批量测试

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

public class DemoApplicationTests {
    @Autowired
    private RedisService redisService;

    @Test
    public 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.mfbz.cn/a/872434.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VMwareWorkstation安装Kali系统教程

Kali系统&#xff0c;全名为Kali Linux&#xff0c;为渗透测试和网络安全领域提供一个全面的工具集合。Kali系统预装了各种用于渗透测试和漏洞利用的工具&#xff0c;包括端口扫描、密码破解、网络嗅探、漏洞分析等。这些工具可以帮助安全专业人员评估和测试网络的安全性&#…

实例讲解Simulink应用层开发CAN报文解包及CAN信号设置方法

在VCU应用层开发中&#xff0c;在输入信号中主要包括开关信号、模拟信号、CAN信号、PWM信号等&#xff0c;其中CAN通讯由于通讯质量高&#xff0c;传输数据量大&#xff0c;采用总线通讯方式节省大量线束&#xff0c;在汽车上尤其是电动汽车上大量应用&#xff0c;当然&#xf…

数图亮相第三届中国区域零售创新峰会:共绘零售新蓝图,携手迈向新征程

8月31日&#xff0c;备受瞩目的第三届中国区域零售创新峰会在历史悠久的湖北襄阳圆满落下帷幕。在这场零售行业的盛会上&#xff0c;数图信息科技作为重要参会企业&#xff0c;积极参与其中&#xff0c;与众多行业精英共聚一堂&#xff0c;共同擘画零售业的宏伟蓝图。以下是本次…

C/C++ 中的算术运算及其陷阱(详解,举例分析)

在C/C编程中&#xff0c;算术运算是非常基础且常用的操作。然而&#xff0c;这些看似简单的运算背后却隐藏着一些潜在的陷阱&#xff0c;如果不加以注意&#xff0c;可能会导致程序出现难以预料的错误。本文将探讨C/C中常见的算术运算及其潜在的陷阱&#xff0c;并通过实例进行…

告别格式不兼容烦恼!ape转换mp3,分享3个简单方法

各位读者们&#xff0c;你们是否有过这种体验&#xff1a;满怀期待地在网上下载一首好听的歌曲&#xff0c;结果怎么点击手机都播放不了&#xff0c;定睛一看&#xff0c;弹窗显示“无法播放该音频文件”。这是为什么呢&#xff1f;原来那首歌的音频格式是ape&#xff0c;不被手…

iOS——关联对象学习补充

分类 在分类中添加属性会生成对应的成员变量&#xff0c;会生成对应的setter和getter方法的声明&#xff0c;但是不会生成setter和getter方法的实现。分类中的可以写property&#xff0c;会编译通过&#xff0c;但是引用变量会报错。分类中可以/只能访问原有类中.h中的属性。如…

如何选择合适的变压吸附制氧设备

在选择合适的变压吸附(Pressure Swing Adsorption, PSA)制氧设备时&#xff0c;需要综合考虑多个因素以确保设备能够高效、稳定地运行&#xff0c;满足特定应用场景的需求。以下是一些关键步骤和考虑因素&#xff0c;帮助您做出明智的决策。 1. 明确应用需求 明确您的制氧需求至…

visual studio 2022更新以后,之前的有些工程编译出错,升级到Visual studio Enterprise 2022 Preview解决

系列文章目录 文章目录 系列文章目录前言一、解决方法 前言 今天遇到一个问题&#xff1a;visual studio 2022升级成预览版以后&#xff0c;之前的有些工程编译出错。首先代码、项目设置都没有改变&#xff0c;只是更新了visual studio 2022。 在编译工程时&#xff0c;编译器…

Team Render 上的 Redshift 照明与我的编辑机器上的不同(如何缓存 Redshift GI)

有时&#xff0c;您的灯光在另一台机器&#xff08;例如属于 Team Render 农场的机器&#xff09;上看起来会与在主/编辑机器上看起来不同。这是因为&#xff0c;即使使用相似或相同的硬件&#xff0c;一台机器计算全局照明的方式与另一台机器也会有所不同。 这可能会导致光线…

Docker 部署 Kibana (图文并茂超详细)

部署 Kibana ( Docker ) [Step 1] : 拉取 Kibana 镜像 docker pull kibana:7.14.0[Step 2] : 创建目录 ➡️ 启动容器 ➡️ 拷贝文件 ➡️ 授权文件 ➡️ 删除容器 # 创建目录 mkdir -p /data/kibana/{conf,plugins}# 启动容器 docker run --name kibana --restartalways \…

科普神文,一次性讲透AI大模型的核心概念

令牌&#xff0c;向量&#xff0c;嵌入&#xff0c;注意力&#xff0c;这些AI大模型名词是否一直让你感觉熟悉又陌生&#xff0c;如果答案肯定的话&#xff0c;那么朋友&#xff0c;今天这篇科普神文不容错过。我将结合大量示例及可视化的图形手段&#xff0c;为你由浅入深一次…

Centos Stream9系统安装及网络配置详解

1.镜像下载 如未拥有系统镜像文件的伙伴可通过前往下面的连接进行下载&#xff0c;下载完成后需将其刻录至U盘中。 PS&#xff1a;该U盘应为空盘&#xff0c;刻录文件会导该盘格式化&#xff0c;下载文件选择dvd1.iso完整包&#xff0c;适用于本地安装。 下载地址&#xff1…

恋爱相亲交友系统源码原生源码可二次开发APP 小程序 H5,web全适配

直播互动&#xff1a;平台设有专门的直播间&#xff0c;允许房间主人与其他异性用户通过视频连线的方式进行一对一互动。语音视频交流&#xff1a;异性用户可以发起语音或视频通话&#xff0c;以增进了解和交流。群组聊天&#xff1a;用户能够创建群聊&#xff0c;邀请自己关注…

【云计算】什么是云计算服务|为什么出现了云计算|云计算的服务模式

文章目录 什么是云计算服务本地部署VS云计算SaaS PaaS IaaS公有云、私有云、混合云为什么优先发展云计算服务的厂商是亚马逊、阿里巴巴等公司 什么是云计算服务 根据不同的目标用户&#xff0c;云计算服务&#xff08;Cloud Computing Services&#xff09;分为两种&#xff1…

探索动销方案创新路径,开启企业增长新引擎

在当今竞争激烈的市场中&#xff0c;动销方案的重要性不言而喻。然而&#xff0c;传统动销手段已难以应对多变的市场环境&#xff0c;企业急需探索创新路径。 当前动销方案面临哪些挑战呢&#xff1f; 首先&#xff0c;消费者需求越发多样化&#xff0c;他们追求个性化和多元化…

如何修复软件中的BUG

笔者上一篇博文《如何开发出一款优秀的软件》主要讲了如何开发一款优秀的软件及相应的必要条件。但对一个已上线&#xff0c;已经成型的产品&#xff0c;该如何解决存在的bug呢&#xff1f;这是本文要阐述的内容。 在这里&#xff0c;首先说一下bug的种类及bug严重程度分类&…

QT: Unable to create a debugging engine.

1.问题场景&#xff1a; 第一次安装QT&#xff0c;没有配置debug功能 打开控制面板》程序》找到Kit 重启电脑即可 2.问题场景&#xff1a; qt原本一直好好的&#xff0c;突然有天打开运行调试版本&#xff0c;提示Unable to create a debugging engine.错误。这个是指无法创…

【计算机网络】TCP连接如何确保传输的可靠性

一、确保可靠传输的机制 TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、提供可靠交付的、面向字节流的、支持全双工的传输层通信协议 1、序列号 seq TCP头部中的序号&#xff0c;占32位&#xff08;4字节&#xff09;&#xff1b; 发送方给报文段分配一个序列号&a…

如何锻炼自己深度思考的能力?4个方法让你快速看清事物的本质!

我们每天都会接触到海量的信息&#xff0c;但真正的智慧并不在于掌握多少信息&#xff0c;而在于如何从中提炼出有价值的知识&#xff0c;并对其进行深刻的理解与运用。 本周想和大家探讨一下深度思考的重要性&#xff0c;同时分享一些实用的方法和技巧&#xff0c;希望能帮你…

STM32(一)简介

一、stm32简介 1.外设接口 通过程序配置外设来完成功能 2.系统结构 3.引脚定义 4.启动配置 5.最小系统电路