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=7777

spring.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%n

1ogging.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
     */
    @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;
    }
}
// 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;

    @Bean
    public 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 {

    @Autowired
    private 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 {

    @Autowired
    private 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在这里插入图片描述

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

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

相关文章

【编译器】VSCODE编译C语言

【编译器】VSCODE编译C语言 文章目录 [TOC](文章目录) 前言一、下载配置二、代码1.main.c2.lanuch3.task 三、编译运行——方法一&#xff1a;编译器运行1.编译&#xff1a;终端-运行生成任务&#xff08;ctrlshiftB&#xff09;2.运行&#xff1a;运行-启动调试&#xff08;F5…

信息安全访问控制、抗攻击技术、安全体系和评估(高软42)

系列文章目录 信息安全访问控制、抗攻击技术、安全体系和评估 文章目录 系列文章目录前言一、信息安全技术1.访问控制2.抗攻击技术 二、欺骗技术1.ARP欺骗2.DNS欺骗3.IP欺骗 三、抗攻击技术1.端口扫描2.强化TCP/IP堆栈 四、保证体系和评估1.保证体系2.安全风险管理 五、真题在…

1 、六气概念-六气内涵

复泰中医体系里&#xff0c;木火土金水&#xff0c;属于传统中医理论的5分法。 有六气&#xff1a;厥阴风木、少阴君火、少阳相火、太阴湿土、阳明燥金、太阳寒水&#xff0c;属于6分法。 五行的体系用在补虚的体系里。 六气的体系用于泻实的体系里。 一、六气概念 天有六气&a…

svn删除所有隐藏.svn文件,文件夹脱离svn控制

新建一个文件&#xff0c;取名remove-svn-folders.reg&#xff0c;输入如下内容&#xff1a; Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] "Delete SVN Folders" [HKEY_LOCAL_MACHINE\SOFTWARE\Class…

【Python 数据结构 10.二叉树】

目录 一、二叉树的基本概念 1.二叉树的定义 2.二叉树的特点 3.特殊的二叉树 Ⅰ、斜树 Ⅱ、满二叉树 Ⅲ、完全二叉树 Ⅳ、完全二叉树和满二叉树的区别 4.二叉树的性质 5.二叉树的顺序存储 Ⅰ、完全二叉树 Ⅱ、非完全二叉树 Ⅲ、稀疏二叉树 6.二叉树的链式存储 7.二叉树的遍历概念…

Windsuf 连接失败问题:[unavailable] unavailable: dial tcp...

问题描述 3月6日&#xff0c;在使用Windsuf 时&#xff0c;遇到以下网络连接错误&#xff1a; [unavailable] unavailable: dial tcp 35.223.238.178:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of…

Hadoop八股

Hadoop八股 HadoopMapReduce考点MR on Yarn 分布式工作原理shuffle&#xff1a;MapTask 和 ReduceTask的处理流程MR中的MapTask 和 ReduceTask 的数量决定MR和Spark两者Shuffle的区别简单讲一下map- reduce 原理**MapReduce 的核心概念****MapReduce 的工作流程****MapReduce 的…

Android15请求动态申请存储权限完整示例

效果: 1.修改AndroidManifest.xml增加如下内容: <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-perm

10.RabbitMQ集群

十、集群与高可用 RabbitMQ 的集群分两种模式,一种是默认集群模式,一种是镜像集群模式&#xff1b; 在RabbitMQ集群中所有的节点(一个节点就是一个RabbitMQ的broker服务器) 被归为两类:一类是磁盘节点,一类是内存节点&#xff1b; 磁盘节点会把集群的所有信息(比如交换机、绑…

ajax之生成一个ajax的demo示例

目录 一. node.js和express ​二. 使用express创建后端服务 三. 创建前端 一. node.js和express ajax是前端在不刷新的情况下访问后端的技术&#xff0c;所以首先需要配置一个后端服务&#xff0c;可以使用node.js和express。 首先生成一个空项目&#xff0c;新建main目录…

unity学习64,第3个小游戏:一个2D跑酷游戏

目录 学习参考 素材资源导入 1 创建项目 1.1 创建1个2D项目 1.2 导入素材 2 背景图bg 2.0 bg素材 2.1 创建背景 2.2 修改素材&#xff0c;且修改摄像机等 2.2.1 修改导入的原始prefab素材 2.2.2 对应调整摄像机 2.2.3 弄好背景 2.3 背景相关脚本实现 2.3.1 错误…

PyTorch系列教程:编写高效模型训练流程

当使用PyTorch开发机器学习模型时&#xff0c;建立一个有效的训练循环是至关重要的。这个过程包括组织和执行对数据、参数和计算资源的操作序列。让我们深入了解关键组件&#xff0c;并演示如何构建一个精细的训练循环流程&#xff0c;有效地处理数据处理&#xff0c;向前和向后…

PX4中的DroneCAN的实现库Libuavcan及基础功能示例

简介 Libuavcan是一个用C编写的可移植的跨平台库&#xff0c;对C标准库的依赖小。它可以由几乎任何符合标准的C编译器编译&#xff0c;并且可以在几乎任何体系结构/OS上使用。 在 DroneCAN 中&#xff0c;Libuavcan 有一个 DSDL 编译器&#xff0c;将 DSDL 文件转换为 hpp 头…

计算机网络(1) 网络通信基础,协议介绍,通信框架

网络结构模式 C/S-----客户端和服务器 B/S -----浏览器服务器 MAC地址 每一个网卡都拥有独一无二的48位串行号&#xff0c;也即MAC地址&#xff0c;也叫做物理地址、硬件地址或者是局域网地址 MAC地址表示为12个16进制数 如00-16-EA-AE-3C-40 &#xff08;每一个数可以用四个…

PCA(主成分分析)核心原理

一、PCA&#xff08;主成分分析&#xff09;核心原理 即主成分分析技术&#xff0c;又称主分量分析技术&#xff0c;旨在利用降维的思想&#xff0c;把多指标转化为少数几个综合指标。在统计学中&#xff0c;主成分分析PCA是一种简化数据集的技术。它是一个线性变换。这个变换…

SpringBoot-模拟SSE对话交互

SpringBoot-模拟SSE对话交互 后端使用SSE进行会话&#xff0c;前端使用Html模拟大模型的问答交互->【前端】【后端】 1-学习目的 本项目代码仓库&#xff1a;https://gitee.com/enzoism/springboot_sse 1-核心知识点 1&#xff09;什么是SSE协议->客户端发起一次请求&am…

2025DNS二级域名分发PHP网站源码

安装教程 1.程序必须使用PHP8.1 2.将扩展ixed.8.1.lin放入/www/server/php/81/lib/php/extensions/no-debug-non-zts-20210902 3.打开宝塔→软件商店→PHP8.1→配置文件 4.放入&#xff1a;extensionixed.8.1.lin 5.重启PHP8.1 6.新建站点&#xff08;mysql5.6-5.7andPHP8.1&a…

Matlab实现车牌识别

车牌识别技术作为现代智能交通系统、安防监控以及诸多车辆管理应用场景中的关键环节&#xff0c;正发挥着日益重要的作用&#xff0c;它能够自动、快速且精准地从车辆图像或视频流中提取车牌信息&#xff0c;实现车辆身份的智能化识别。 技术原理 车牌识别主要依托于图像处理、…

C语言——链表

大神文献&#xff1a;https://blog.csdn.net/weixin_73588765/article/details/128356985 目录 一、链表概念 1. 什么是链表&#xff1f; 1.1 链表的构成 2. 链表和数组的区别 数组的特点&#xff1a; 链表的特点&#xff1a; 二者对比&#xff1a; 二…

国产化板卡设计原理图:2330-基于FMC接口的JFM7K325T PCIeX4 3U PXIe接口卡

基于FMC接口的JFM7K325T PCIeX4 3U PXIe接口卡 一、板卡概述 本板卡基于 FPGAJFM7K325T 芯片&#xff0c;pin_to_pin兼容FPGAXC7K410T-2FFG900 &#xff0c;支持PCIeX8、64bit DDR3容量2GByte&#xff0c;HPC的FMC连接器&#xff0c;板卡支持PXIE标准协议&#xff0c;其中XJ3…