Redis整合SpringBoot微服务基础操作

前言

首先我们先知道类似于JDBC的连接中间件在redis之间使用的是啥

首先是Jedis,这是最初代的连接redis客户端 

操作也是非常的简单

Jedis

首先我们先介绍这个

我们只需要引入对应的pom文件依赖

   <!--SpringBoot通用依赖模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.3.1</version>
        </dependency>
        <!--lettuce-->
        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
            <version>6.2.1.RELEASE</version>
        </dependency>
        <!--SpringBoot与Redis整合依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!--swagger2-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

这个连接中间件主要是线程池不安全

所以才有了后续的迭代

我们先使用一下试试看

注意这里的端口和ip写自己的

如果不知道可以使用对应的命令进行查看

ifconfig  //linux

ipconfig //windows
public class JedisDemo {
    public static void main(String[] args) {
        //获得连接connect
        Jedis jedis = new Jedis("192.168.188.136", 6379);
        jedis.auth("abc123");
        //获得客户端之后可以像JDBC一样可以获取
        System.out.println(jedis.ping());


        //获取keys *
        Set<String> keys = jedis.keys("*");
        System.out.println(keys);

        //设置一个
        jedis.set("k3","v333");
        System.out.println(jedis.get("k3"));


        //list
        jedis.lpush("list","aaa","bbb","ccc");
        System.out.println(jedis.lrange("list",0,-1));


    }
}

然后我们可以进对应的客户端查看就会发现对应的数据已经写入了

这里的乱码问题我们暂时不考虑,主要是编码和序列化的问题,是因为我之前测试集群输入中文的时候产生的,大家不必在意

Lettuce

有人会问有了Jedis为啥使用这个(中文翻译叫生菜)生菜呢?

其实是因为在使用Jedis的时候,会多次创建多个连接池

相对来说如果支持8w个请求,那么也肯定内内存撑爆了

而且其是线程不安全的

这里的Lettuce底层使用netty,可以确保只用一个连接池保证多路复用

说了这么多我们就来看看对应的Lettuce是怎么使用的吧

我们只需要对应的pom依赖导入

    <!--lettuce-->
        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
            <version>6.2.1.RELEASE</version>
        </dependency>

这里主要体现链式编程,我们也是一样的配置

我们先配置对应的URL

在座位参数传给对应的客户端

然后创建对应操作command

public class LettuceDemo {
    public static void main(String[] args)
    {
        //1.使用构建器链式编程来构建redisURI
        RedisURI redisURI = RedisURI.builder()
                .redis("192.168.188.136")
                .withPort(6379)
                .withAuthentication("default", "abc123")
                .build();

        //获取客户端
        RedisClient redisClient = RedisClient.create(redisURI);
        StatefulRedisConnection<String, String> connect = redisClient.connect();
        
        //创建操作的command
        RedisCommands<String, String> sync = connect.sync();

        //业务操作
        List<String> keys = sync.keys("*");
        System.out.println(keys);


        //关闭资源
        connect.close();
    }
}

虽然体现的日志信息比较多

但是也可以看到完整的信息

RedisTemplate(重中之重)

下面我们来介绍使用的主流 

RedisTemplate,这也是被Spring集成的框架

我们可以在对应的jar包上看到起集成了Lettuce

其实是因为在Lettuce刚开发出来的时候Spring掩盖住了它的光芒

所以使用RedisTemplate更多

他还有一个常用的子类,叫做StringRedisTemplate

首先依然是引入对应的依赖

        <!--SpringBoot与Redis整合依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!--swagger2-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

然后我们就可以进行对应的开发了

然后就是对应的配置yml文件

注意修改ip为自己的ip哦

server.port=7777

spring.application.name=redis7_study

# ========================logging=====================
logging.level.root=info
logging.level.com.atguigu.redis7=info
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n 

logging.file.name=D:/mylogs2023/redis7_study.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n

# ========================swagger=====================
spring.swagger2.enabled=true
#在springboot2.6.X结合swagger2.9.X会提示documentationPluginsBootstrapper空指针异常,
#原因是在springboot2.6.X中将SpringMVC默认路径匹配策略从AntPathMatcher更改为PathPatternParser,
# 导致出错,解决办法是matching-strategy切换回之前ant_path_matcher
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

# ========================redis单机=====================
spring.redis.database=0
# 修改为自己真实IP
spring.redis.host=192.168.111.185
spring.redis.port=6379
spring.redis.password=111111
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

然后注意修改对应的主启动类

@SpringBootApplication
public class Redis7Study7777
{
    public static void main(String[] args)
    {
        SpringApplication.run(Redis7Study7777.class,args);
    }
}

我们这里采用一个微服务的架构,存储一个订单信息

架构大概是这样的

这里我们业务就在service层中写

@Service
@Slf4j
public class OrderService {
    public static final String ORDER_KEY = "order:";

    @Resource
    private RedisTemplate redisTemplate;
//@Resource
//private StringRedisTemplate redisTemplate;
    public void addOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000)+1;
        String serialNo = UUID.randomUUID().toString();

        String key = ORDER_KEY + keyId;
        String value = "京东订单"+serialNo;

        redisTemplate.opsForValue().set(key, value);
        log.info("添加订单成功,keyId:{},value:{}", keyId, value);
    }


    public String getOrder(int keyId) {
        return (String) redisTemplate.opsForValue().get(ORDER_KEY + keyId);
    }


}

后面我们配置一下swagger直接测试接口

 下面我们进行简单的get和add方法的书写以及swagger测试框架的配置

swagger配置

@Configuration
@EnableSwagger2
public class SwaggerConfig
{
    @Value("${spring.swagger2.enabled}")
    private Boolean enabled;

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(enabled)
                .select()
                .apis(RequestHandlerSelectors.basePackage("org.example")) //你自己的package
                .paths(PathSelectors.any())
                .build();
    }

}

对应的包记得改成自己的

然后我们写controller接口


@RestController
@Slf4j
@Api(tags ="订单接口")
public class OrderController {
    @Resource
    private OrderService orderService;

    @ApiOperation("添加订单")
    @RequestMapping("/order/add")
    public void addOrder()
    {
        orderService.addOrder();
    }

    @ApiOperation("查询订单")
    @RequestMapping("/order/{keyId}")
    public void getOrder(@PathVariable int keyId)
    {
        orderService.getOrder(keyId);
    }
}

然后直接使用swagger进行对应的接口测试操作

这里为了演示一个错误,我们使用最原始的RedisTemplate

这时候我们就会发现写入的中文是乱码信息

解决方式这里提供两种方案

首先是使用StringRedisTemplate解决问题

因为默认RedisTemplate默认是采用对应的JDK来进行序列化的

我们使用StringRedisTemplate可以解决问题

但是我们查看对应的值还是不行

我们只需要在链接客户端的时候加上

redis-cli -a abc123 --raw

就可以解决中文乱码的问题了

如果就想使用RedisTemplate可以直接进行配置,在开始的时候就使用

StringRedisTemplate进行对应的初始化

只需要加上一个Config类

@Configuration
public class RedisConfig
{
    /**
     * redis序列化的工具配置类,下面这个请一定开启配置
     * 127.0.0.1:6379> keys *
     * 1) "ord:102"  序列化过
     * 2) "\xac\xed\x00\x05t\x00\aord:102"   野生,没有序列化过
     * this.redisTemplate.opsForValue(); //提供了操作string类型的所有方法
     * this.redisTemplate.opsForList(); // 提供了操作list类型的所有方法
     * this.redisTemplate.opsForSet(); //提供了操作set的所有方法
     * this.redisTemplate.opsForHash(); //提供了操作hash表的所有方法
     * this.redisTemplate.opsForZSet(); //提供了操作zset的所有方法
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory)
    {
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();

        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        //设置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}

即可解决问题

小总结

使用redis-cli -a "password" -p  port --raw

就可以解决对应的中文乱码问题(根据键查看值的时候)

然后对应的序列化问题使用StringRedisTemplate就可以

注意swagger的包和对应的properties文件记得修改成自己的

集群操作配置

首先我们开启对应的集群

配置对应的配置信息

将单机的配置文件修改成对集群的

使用cluster nodes 查看对应的集群信息

我们试试对应的写入能否成功

# ========================redis集群=====================
spring.redis.password=abc123


# 获取失败 最大重定向次数
spring.redis.cluster.max-redirects=3
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.cluster.nodes=192.168.188.136:6381,192.168.188.136:6382,192.168.188.137:6383,192.168.188.137:6384,192.168.188.138:6385,192.168.188.138:6386

我们尝试一下是否能成功写入

我们发现插入是成功的

我们再验证一下主从的上位情况是否能成功

我们先把主机干掉

我们尝试直接干掉138,查看136是否会上位

我们发现6382已经成为master了

然后我们再次尝试写入

我们发现一直失败了

然后到超时时间就直接失败了

我们可以配置对应的动态刷新拓扑结构或者是定时刷新就可以解决问题

因为这里其实是redis客户端的拓扑结构变化了

其实对应的微服务对其是无感应的

我们只需让其有感知即可

也就是对对应的配置文件进行修改

# ========================redis集群=====================
spring.redis.password=abc123

#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
spring.redis.lettuce.cluster.refresh.adaptive=true
#定时刷新
spring.redis.lettuce.cluster.refresh.period=2000
# 获取失败 最大重定向次数
spring.redis.cluster.max-redirects=3
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.cluster.nodes=192.168.188.136:6381,192.168.188.136:6382,192.168.188.137:6383,192.168.188.137:6384,192.168.188.138:6385,192.168.188.138:6386

其实还有两种方式,但是我们不推荐

1.底层使用Jedis

2.修改连接池的源码解决问题

解决完之后就是以下的结果

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

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

相关文章

uniapp使用uQRCode页面不显示也不报错

我使用的版本是&#xff1a;4.0.6 引入到项目中后根据官方的配置教程进行配置&#xff1a; 但是页面上就是不显示&#xff0c;也不报错&#xff0c;看官网发现步骤也没问题 解决方法&#xff1a; 这句话代表的是uQrcode会被自动引用注册&#xff0c;但是你引过组件库或者别的…

51单片机课设

1.51最小系统板原理图介绍 复位电路&#xff1a;&#xff08;简单的RC电路&#xff09; 在电路图中&#xff0c;电容的的大小是10uF&#xff0c;电阻的大小是10k。 当接通VCC后&#xff1a; 电容还没开始充电&#xff0c;电容电压为0&#xff0c;R7的电压为5V,然后电容开始充电…

盲盒小程序库存管理的关键策略

随着盲盒经济的兴起&#xff0c;越来越多的商家开始投入盲盒小程序的开发与运营。然而&#xff0c;在享受市场红利的同时&#xff0c;库存管理的问题也随之而来。合理的库存管理不仅能够满足用户需求&#xff0c;还能有效优化库存周转率&#xff0c;提升商家的盈利能力。本文将…

操作系统入门系列-MIT6.828(操作系统工程)学习笔记(四)---- C语言与计算机架构(Programming xv6 in C)

系列文章目录 操作系统入门系列-MIT6.S081&#xff08;操作系统&#xff09;学习笔记&#xff08;一&#xff09;---- 操作系统介绍与接口示例 操作系统入门系列-MIT6.828&#xff08;操作系统工程&#xff09;学习笔记&#xff08;二&#xff09;----课程实验环境搭建&#x…

【图像识别系统】表情识别Python+人工智能深度学习+TensorFlow+卷积算法网络模型+图像识别

表情识别系统&#xff0c;本系统使用Python作为主要编程语言&#xff0c;通过TensorFlow搭建ResNet50卷积神经算法网络模型&#xff0c;通过对7种表情图片数据集&#xff08;‘Neutral’, ‘Anger’, ‘Disgust’, ‘Fear’, ‘Happy’, ‘Sad’, ‘Surprise’&#xff09;进行…

安装存储器的段描述符并加载GDTR

代码清单 ;代码清单12-1;文件名&#xff1a;c12_mbr.asm;文件说明&#xff1a;硬盘主引导扇区代码;创建日期&#xff1a;2011-5-16 19:54&#xff1b;修改于2022-02-16 11:15;设置堆栈段和栈指针mov ax, csmov ss, axmov sp, 0x7c00;计算GDT所在的逻辑段地址12 mov ax, [c…

视图的相关操作

4.1.1 创建视图 语法格式&#xff1a;create [ or replace ] view view_name [ ( column_list ) ] as select_statement [ with [ cascade | local ] check option ] 说明&#xff1a; &#xff0…

Redis的SDS数据结构解决C语言字符串缺陷

redis设计了SDS这一数据结构来表示字符串而不是使用c语言的字符串&#xff1a;字符数组 那么redis为什么要大费周章自己设计字符串呢&#xff1f; 答案是C语言字符串有缺陷 1.获取字符串长度&#xff0c;需要遍历字符数组&#xff0c;时间复杂度是O&#xff08;N&#xff09…

167.二叉树:另一棵树的字树(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

PostgreSQL 16 小课推广

PostgreSQL 16 小课推广 1. PostgreSQL 16 基础知识 PostgreSQL 16 的特点与优势安装与配置PostgreSQL 16数据库和表的基本概念与操作数据类型与约束SQL 语言基础 2. 数据查询与操作 SELECT 语句的使用聚合函数与分组查询子查询与连接查询数据插入、更新与删除视图与索引的…

二维码生成

摘要 QRCoder 是一个功能强大的 C# 库&#xff0c;用于生成 QR 码。QR 码是一种二维码&#xff0c;可以存储大量的信息&#xff0c;并且具有良好的识别率和存储容量。使用 QRCoder&#xff0c;用户可以方便地生成各种类型的 QR 码&#xff0c;包括 URL、文本、电话号码、电子邮…

<网络安全VIP>第二篇《工业控制软件》

1 PLC PLC,(Programmable Logic Controller),可编程逻辑控制器(PLC)是种专门为在工业环境下应用而设计的数字运算操作电子系统。 2 DCS 四、DCS的发展趋势 一、DCS的基本定义 DCS是分布式控制系统(Distributed Control System)的英文缩写,在国内自控行业又称之为集…

运放IC:HC358:1MHz,轨到轨I/O,低功耗运算放大ic,供应:传感器压力传感放大器移动通讯设备音频输出便携应用烟雾监测电池驱动的设备

运放IC&#xff1a; HC358&#xff1a;1MHz&#xff0c;轨到轨I/O&#xff0c;低功耗运算放大ic 概述&#xff1a;HC358是一款轨到轨输入输出&#xff0c;电压反馈运算放大 器。输入共模范围和输出摆幅较大&#xff0c;最低工作电源电压仅 为2.1V,最高电压可达5.5V。工作环…

冥想第一千一百七十八天

1.周末&#xff0c;早上先骑着电车到绿谷公园拿了姐给的精油&#xff0c;40分钟到家。 2.早上带着媳妇吃了饭&#xff0c;等丈母娘和小侄子。一起去荥泽水乡特别的推荐。感受特别好玩。 3.晚上带着丈母娘和小侄子吃了饭&#xff0c;给送到中原福塔。回来都都12点了。 4.累的&am…

【Nacos】docker-compose启动nacos v2.2.3,启动时修改默认密码不使用naocs

1. 背景 出于安全考虑&#xff0c;我司DevOps平台自动部署的容器化nacos密码不能是弱密码或默认值 但是nacos-v2.2.3官方镜像启动后会初始化nacos用户密码为nacos&#xff0c;修改启动时的变量并没有生效。 2. 部署验证 2.1 yml文件如下 注意将derby库的初始化文件挂载出来…

群体优化算法---蜂群优化算法应用于数据挖掘

介绍 蜂群优化算法&#xff08;Bee Algorithm, BA&#xff09;及其变种主要模拟蜜蜂的觅食行为&#xff0c;以解决复杂的优化问题。这类算法通过蜜蜂之间的信息交流和协作来探索解空间&#xff0c;寻找全局最优解。主要应用于参数优化&#xff0c;结构优化&#xff0c;机器学习…

初讲解运算符重载

运算符的重载 运算符重载基本概念运算符重载入门技术推演运算符重载碰上友元函数运算符重载的限制 什么是运算符重载&#xff1f; 运算符重载基本概念 所谓重载&#xff0c;就是重新赋予新的含义。 函数重载就是对一个已有的函数赋予新的含义&#xff0c;使之实现新功能&#x…

[Algorithm][动态规划][回文串问题][回文子串][最长回文子串][分割回文串Ⅳ]详细讲解

目录 0.原理讲解1.回文子串1.题目链接2.算法原理详解3.代码实现 2.最长回文子串1.题目链接3.代码实现 3.分割回文串 IV1.题目链接2.算法原理详解3.代码实现 0.原理讲解 动态规划能够将所有的子串是否是回文的信息&#xff0c;保存在dp表里面状态表示一般经验&#xff1a;以[i,…

【Redis】redis高阶-使用zset实现延时队列

Hi,大家好&#xff0c;我是抢老婆酸奶的小肥仔。 最近在使用redis时&#xff0c;就想能不能用其实现消息队列&#xff1f;也在网上看了下其他小伙伴写的实现&#xff0c;结合自身业务实现了如下消息队列&#xff0c;希望对大家有用。 废话不多说&#xff0c;直接开撸。 1、为…

Kafka之Broker原理

1. 日志数据的存储 1.1 Partition 1. 为了实现横向扩展&#xff0c;把不同的数据存放在不同的 Broker 上&#xff0c;同时降低单台服务器的访问压力&#xff0c;我们把一个Topic 中的数据分隔成多个 Partition 2. 每个 Partition 中的消息是有序的&#xff0c;顺序写入&#x…