Redis|Springboot集成Redis

文章目录

    • 总体概述
    • 本地Java连接Redis常见问题
    • 集成Jedis
    • 集成lettuce
    • 集成RedisTemplate——推荐使用
      • 连接单机
      • 连接集群

在这里插入图片描述

总体概述

  • jedis-lettuce-RedisTemplate三者的联系
    • jedis第一代
    • lettuce承上启下
    • redistemplate着重使用

本地Java连接Redis常见问题

  • bind配置请注释掉
  • 保护模式设置为no
  • Linux系统的防火墙设置
  • Redis服务器的IP地址和密码是否正确
  • 忘记写访问redis的服务端口号和auth密码

集成Jedis

  • 是什么:Jedis Client是Redis官网推荐的一个面向Java客户端,库文件实现了对各类API进行封装调用
  • 步骤
    1. 建Module
    2. 改POM.xml
    3. 写application.yaml
    4. 主启动
    5. 业务类
<?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>2.7.11</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.luojia</groupId><artifactId>redis7_study</artifactId><version>0.0.1-SNAPSHOT</version><name>redis7_study</name><description>Demo project for Spring Boot</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><junit.version>4.12</junit.version><log4j.version>1.2.17</log4j.version><lombok.version>1.16.18</lombok.version></properties><dependencies><!--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><!-- 通用基础配置 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</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>
server.port=7777
spring.application.name=redis7_study

在这里插入图片描述在这里插入图片描述

集成lettuce

  • 是什么:Lettuce是一个Redis的Java驱动包,Lettuce翻译为生菜,就是吃的那种生菜

  • lettuce VS Jedis在这里插入图片描述

  • 改POM在这里插入图片描述

  • 业务类在这里插入图片描述在这里插入图片描述

集成RedisTemplate——推荐使用

连接单机

  • boot整合Redis基础演示
  • 建module:redis7_study
  • 改pom
<!-- 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
server.port=7777spring.application.name=redis7_study# ===========================logging===========================
logging.level.root=info
logging.1evel.com.luojia.redis7_study.redis7=info
1ogging.pattern.console=%d{yyyy-MM-dd HH:m:ss.SSS} [%thread] %-5level %1ogger- %msg%n1ogging.file.name=F:\workspace\数据结构和算法\Learning-in-practice\Redis\redis7-study
1ogging.pattern.fi1e=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n# ===========================swagge===========================
spring.swagger2.enabled=true
#在springboot2.6.X结合swagger2.9.X会提示documentationPluginsBootstrapper空指针异常,
#原因是在springboot2.6.X中将SpringMVC默认路径匹配策略MAntPathMatcher更改为athPatternParser,
#导致出错,解决办法是matching-strategy 切换回之前ant_path_matcher
spring.mvc.pathmatch.matching-strategy=ant_path_matcher# ===========================redis单机===========================
spring.redis.database=0
#修改为自己真实IP
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.lettuce.pool.max-active=8
spring.redis.1ettuce.pool.max-wait=-1ms
spring.redis.1ettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
  • 主启动在这里插入图片描述
  • 业务类-配置类
// RedisConfig
package com.luojia.redis7_study.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {/*** *redis序列化的工具定置类,下面这个请一定开启配置* *127.0.0.1:6379> keys ** *1) “ord:102” 序列化过* *2)“\xaclxedlxeelx05tixeelaord:102” 野生,没有序列化过* *this.redisTemplate.opsForValue(); //提供了操作string类型的所有方法* *this.redisTemplate.opsForList();// 提供了操作List类型的所有方法* *this.redisTemplate.opsForset(); //提供了操作set类型的所有方法* *this.redisTemplate.opsForHash(); //提供了操作hash类型的所有方认* *this.redisTemplate.opsForZSet(); //提供了操作zset类型的所有方法* param LettuceConnectionFactory* return*/@Beanpublic RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(lettuceConnectionFactory);// 设置key序列化方式stringredisTemplate.setKeySerializer(new StringRedisSerializer());// 设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;}
}
// SwaggerConfig
package com.luojia.redis7_study.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;import java.time.LocalDate;
import java.time.format.DateTimeFormatter;@Configuration
@EnableSwagger2
public class SwaggerConfig {@Value("${spring.swagger2.enabled}")private Boolean enabled;@Beanpublic Docket createRestApi() {return new Docket (DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(enabled).select().apis(RequestHandlerSelectors.basePackage("com.luojia.redis7_study.config")) //你自己的package.paths (PathSelectors.any()).build();}public ApiInfo apiInfo() {return new ApiInfoBuilder().title("springboot利用swagger2构建api接口文档 "+"\t"+ DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDate.now())).description( "springboot+redis整合" ).version("1.0").termsOfServiceUrl("https://github.com/Romantic-Lei").build();}}
  • 业务类-service
package com.luojia.redis7_study.service;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;@Service
@Slf4j
public class OrderService {@Autowiredprivate RedisTemplate redisTemplate;public static final String ORDER_KEY="ord:";public void addOrder() {int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;String serialNo = UUID.randomUUID().toString();String key = ORDER_KEY+keyId;String value = "JD" + serialNo;redisTemplate.opsForValue().set(key, value);log.info("***key:{}", key);log.info("***value:{}", value);}public String getOrderById(Integer keyId) {return (String)redisTemplate.opsForValue().get(ORDER_KEY+keyId);}
}
  • 业务类-controller
package com.luojia.redis7_study.controller;import com.luojia.redis7_study.service.OrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@Slf4j
@Api(tags="订单接口")
public class OrderController {@Autowiredprivate OrderService orderService;@ApiOperation("新增订单")@PostMapping("/order/add")public void addOrder() {orderService.addOrder();}@ApiOperation("根据keyId查询订单")@GetMapping("/order/query")public String queryOrder(Integer keyId) {return orderService.getOrderById(keyId);}}
  • 测试
    • 项目启动,连接swagger:http://localhost:7777/swagger-ui.html
    • 序列化问题在这里插入图片描述
    • 为什么会这样?RedisTemplate使用的是JDK序列化方式(默认)惹的祸在这里插入图片描述
      在这里插入图片描述在这里插入图片描述

连接集群

  • 启动Redis集群6台实例
  • 第一次改写YML
# ===========================redis集群===========================
spring.redis.password=111111
# 获取失败 最大重定向次数
spring.redis.cluster.max-redirects=3
spring.redis.lettuce.pool.max-active=8
spring.redis.1ettuce.pool.max-wait=-1ms
spring.redis.1ettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.cluster.nodes=192.168.111.175:6381,192.168.111.175:6382,192.168.111.176:6383,192.168.111.176:6384
  • 直接通过微服务访问Redis集群:一切正常 (http://localhost:7777/swagger-ui.html)
  • 问题来了:
    1. 人为模拟,master-6381机器意外宕机,手动shutdown
    2. 先对redis集群用命令的方式,手动验证各种读写命令,看看6384是否上位
    3. Redis Cluster集群能自动感知并自动完成主备切换,对应的slave6384会被选举为新的master节点
    4. 通过redis客户端连接6384可以正常进行读写操作
    5. 微服务客户端再次读写访问试试
      • 故障现象

        • SpringBoot客户端没有动态感知RedisCluster的最新集群信息
        • 经典故障-故障演练:Redis Cluster集群部署采用了3主3从拓扑结构,数据读写访问master节点,slave节点负责备份。当master宕机主从切换成功,redis手动OK,but 2个经典故障在这里插入图片描述
      • 导致原因:SpringBoot 2.X版本,Redis默认的连接池采用Lettuce,当Redis集群节点发生变化后,Letture默认是不会刷新节点拓扑

      • 解决方案

        1. 排除lettuce采用Jedis(不推荐)在这里插入图片描述
        2. 修改源码,重写连接工厂实例(极度不推荐)
        3. 刷新节点集群拓扑动态感应在这里插入图片描述
          • 解决方法:
            • 调用 RedisClusterClient.reloadPartitions
            • 后台基于时间间隔的周期刷新
            • 后台基于持续的断开和移动、重定向的自适应更新
      • 第二次改写YML在这里插入图片描述

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

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

相关文章

计算机毕业设计SpringBoot+Vue.js制造装备物联及生产管理ERP系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

基于单片机及传感器的机器人设计与实现

摘要 : 本设计基于单片机及多种传感器 , 完成了一个自主式移动机器人的制作。单片机作为系统检测和控制的核心 , 实现对机器人小车的智能控制。反射式红外光电传感器检测引导线, 使机器人沿轨道自主行走 ; 使用霍尔集成片 , 通过计车轮转过的圈数完成机器人行走路程测量; …

VBA 列方向合并单元格,左侧范围大于右侧范围

实现功能如下&#xff1a; excel指定行列范围内的所有单元格 规则1&#xff1a;每一列的连续相同的值合并单元格 规则2&#xff1a;每一列的第一个非空单元格与其下方的所有空白单元格合并单元 规则3&#xff1a;优先左侧列合并单元格&#xff0c;合并后&#xff0c;右侧的单元…

docker中kibana启动后,通过浏览器访问,出现server is not ready yet

问题&#xff1a;当我在浏览器访问kibana时&#xff0c;浏览器给我报了server is not ready yet. 在网上试了很多方法&#xff0c;都未能解决&#xff0c;下面是我的方法&#xff1a; 查看kibana日志&#xff1a; docker logs -f kibana从控制台打印的日志可以发现&#xff…

Lora模型微调(1): 原理讲解

1. 参数高效微调介绍 参数高效微调(Parameter-Efficient Fine-Tuning, PEFT) 是一种在深度学习模型微调过程中,通过仅更新少量参数来适应新任务的技术。这种方法在保持模型性能的同时,显著减少了计算资源和存储需求,特别适用于大模型(如 GPT、BERT 等)的微调场景。 PE…

【国产Linux | 银河麒麟】麒麟化龙——KylinOS下载到安装一条龙服务,起飞!

&#x1f5fa;️博客地图 &#x1f4cd;一、下载地址 &#x1f4cd;二、 系统安装 本文基于Windows操作系统vmware虚拟机安装 一、下载地址 官网&#xff1a;产品试用申请国产操作系统、麒麟操作系统——麒麟软件官方网站 下载自己需要的版本&#xff0c;完成后&#xff0c…

MySQL(单表)知识点

文章目录 1.数据库的概念2.下载并配置MySQL2.1初始化MySQL的数据2.2注册MYSQL服务2.3启动MYSQL服务2.4修改账户默认密码2.5登录MYSQL2.6卸载MYSQL 3.MYSQL数据模型3.1连接数据库 4.SQL简介4.1SQL的通用语法4.2SQL语句的分类4.3DDL语句4.3.1数据库4.3.2表(创建,查询,修改,删除)4…

解析 SQL,就用 sqlparse!

文章目录 解析 SQL&#xff0c;就用 sqlparse&#xff01;一、背景&#xff1a;为什么你需要 sqlparse&#xff1f;二、什么是 sqlparse&#xff1f;三、如何安装 sqlparse&#xff1f;四、简单易用的库函数1\. parse(sql)2\. format(sql, **options)3\. split(sql)4\. get_typ…

C++vector类

目录 一、vector的使用 1.1、vector的构造&#xff0c;push_back&#xff0c;和 [ ]运算符 1.2、迭代器和范围for 1.3、vector> 和 sort 算法 二、vector的实现 2.1、成员变量 2.2、构造函数&#xff0c;析构函数&#xff0c;赋值重载 ​编辑 2.3、push_back&#x…

模拟调制技术详解

内容摘要 本文系统讲解模拟调制技术原理及Matlab实现&#xff0c;涵盖幅度调制的四种主要类型&#xff1a;双边带抑制载波调幅&#xff08;DSB-SC&#xff09;、含离散大载波调幅&#xff08;AM&#xff09;、单边带调幅&#xff08;SSB&#xff09;和残留边带调幅&#xff08;…

Android APP 启动流程详解(含冷启动、热启动)

目录 一、流程对比图 二、冷启动&#xff08;Cold Launch&#xff09; 2.1 用户点击应用图标&#xff08;Launcher 触发&#xff09; 2.2 AMS 处理启动请求 2.3 请求 Zygote 创建新进程 2.4 初始化应用进程 2.5 创建 Application 对象 2.6 启动目标 Activity 2.7 执行 …

前端项目中export和import的作用

之前写过代码&#xff0c;但是那个时候是使用jspdivcss写页面&#xff0c;jquery负责页面数据展示和数据请求。近期在学习前端&#xff0c;发现有export和import&#xff0c;想起了之前没用过&#xff0c;就研究搜索了一下&#xff0c;发现这个是在 ES6中添加的&#xff0c;难怪…

玩转ChatGPT:GPT 深入研究功能

一、写在前面 民间总结&#xff1a; 理科看Claude 3.7 Sonnet 文科看DeepSeek-R1 那么&#xff0c;ChatGPT呢&#xff1f; 看Deep Research&#xff08;深入研究&#xff09;功能。 对于科研狗来说&#xff0c;在这个文章爆炸的时代&#xff0c;如何利用AI准确、高效地收…

QLabel 介绍

一、介绍 QLabel 是标签&#xff0c;显示类控件。 二、属性 属性说明text显示的文本textFormat文本格式pixmap设置标签里面的图片scaledContexts内容是否自动填充标签&#xff08;用于图片填满标签&#xff09;alignment对齐方式wordWarp文本是否换行indent设置文本缩进marg…

ubuntu 20.04 C++ 源码编译 cuda版本 opencv4.5.0

前提条件是安装好了cuda和cudnn 点击下载&#xff1a; opencv_contrib4.5.0 opencv 4.5.0 解压重命名后 进入opencv目录&#xff0c;创建build目录 “CUDA_ARCH_BIN ?” 这里要根据显卡查询一下,我的cuda是11&#xff0c;显卡1650&#xff0c;所以是7.5 查询方法1&#xff1…

更新Vim使其支持系统剪切板

参考链接 [转]vim如何复制到系统剪贴板 - biiigwang - 博客园 执行命令 sudo apt-get install vim-gtk 可能遇到的报错 原因 旧版本的系统大多使用vim-gtk&#xff0c;在新版本中已经不存在这个软件包 可以通过输入命令查找是否存在 apt search vim-gtk 可以看到并没有…

TMS320F28P550SJ9学习笔记6:SCI所有寄存器__结构体寄存器方式配置 SCI通信初始化__库函数发送测试

继续学习如何使用结构体寄存器的方式配置这款单片机的外设&#xff0c;这里配置SCI通信的初始化 但SCI gpio 的初始化还是调用的库函数比较方便&#xff0c;它的发送部分页调用了库函数 有关收发方面的逻辑&#xff0c;我会在之后重新自己写一次 文章提供测试代码讲解、完整…

静态时序分析STA——2. 数字单元库-(1)

参考文献 [1]Static Timing Analysis for Nanometer Designs A Practical Approach [2]静态时序分析圣经翻译计划——第三章&#xff1a;标准单元库 &#xff08;上&#xff09; 一. 引脚电容 标准单元库的每个cell的每个输入和输出都可以在pin上指定电容。在大多数情况下&…

Spring-事务

Spring 事务 事务的基本概念 &#x1f539; 什么是事务&#xff1f; 事务是一组数据库操作&#xff0c;它们作为一个整体&#xff0c;要么全部成功&#xff0c;要么全部回滚。 常见的事务场景&#xff1a; 银行转账&#xff08;扣款和存款必须同时成功&#xff09; 订单系统…

蓝桥备赛(13)- 链表和 list(下)

一、动态链表 - list (了解) new 和 delete 是非常耗时的操作 在算法比赛中&#xff0c;一般不会使使用 new 和 delete 去模拟实现一个链表。 而且STL 里面的 list 的底层就是动态实现的双向循环链表&#xff0c;增删会涉及 new 和 delete&#xff0c;效率不高&#xff0c;竞赛…