当前位置: 首页 > news >正文

SpringBoot 集成 Redis

本地Java连接Redis常见问题:

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

集成Jedis

jedis是什么

Jedis Client是Redis官网推荐的一个面向java客户端,库文件实现了对各类API进行封装调用。

案例

1、pom.xml

<!--jedis-->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.1</version>
</dependency>

2、测试

public class JedisDemo
{public static void main(String[] args){//连接本地的 Redis 服务,自己的ip和端口和密码Jedis jedis = new Jedis("192.168.111.181",6379);// 如果 Redis 服务设置了密码,需要下面这行,没有就不需要jedis.auth("111111");//keySet<String> keys = jedis.keys("*");for (Iterator iterator = keys.iterator(); iterator.hasNext();) {String key = (String) iterator.next();System.out.println(key);}System.out.println("jedis.exists====>"+jedis.exists("k2"));System.out.println(jedis.ttl("k1"));//String//jedis.append("k1","myreids");System.out.println(jedis.get("k1"));jedis.set("k4","k4_redis");System.out.println("----------------------------------------");jedis.mset("str1","v1","str2","v2","str3","v3");System.out.println(jedis.mget("str1","str2","str3"));//listSystem.out.println("----------------------------------------");//jedis.lpush("mylist","v1","v2","v3","v4","v5");List<String> list = jedis.lrange("mylist",0,-1);for (String element : list) {System.out.println(element);}//setjedis.sadd("orders","jd001");jedis.sadd("orders","jd002");jedis.sadd("orders","jd003");Set<String> set1 = jedis.smembers("orders");for (Iterator iterator = set1.iterator(); iterator.hasNext();) {String string = (String) iterator.next();System.out.println(string);}jedis.srem("orders","jd002");System.out.println(jedis.smembers("orders").size());//hashjedis.hset("hash1","userName","lisi");System.out.println(jedis.hget("hash1","userName"));Map<String,String> map = new HashMap<String,String>();map.put("telphone","138xxxxxxxx");map.put("address","atguigu");map.put("email","zzyybs@126.com");//课后有问题请给我发邮件jedis.hmset("hash2",map);List<String> result = jedis.hmget("hash2", "telphone","email");for (String element : result) {System.out.println(element);}//zsetjedis.zadd("zset01",60d,"v1");jedis.zadd("zset01",70d,"v2");jedis.zadd("zset01",80d,"v3");jedis.zadd("zset01",90d,"v4");List<String> zset01 = jedis.zrange("zset01", 0, -1);zset01.forEach(System.out::println);}
}

集成Lettuce

lettuce是什么

Lettuce是一个Redis的Java驱动包,Lettuce翻译为生菜,没错,就是吃的那种生菜,所以它的Logo长这样。

Jedis 和 Lettuce 区别

案例

1、pom.xml

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

2、测试

@Slf4j
public class LettuceDemo
{public static void main(String[] args){//使用构建器 RedisURI.builderRedisURI uri = RedisURI.builder().redis("192.168.111.181").withPort(6379).withAuthentication("default","111111").build();//创建连接客户端RedisClient client = RedisClient.create(uri);StatefulRedisConnection conn = client.connect();//操作命令apiRedisCommands<String,String> commands = conn.sync();//keysList<String> list = commands.keys("*");for(String s : list) {log.info("key:{}",s);}//Stringcommands.set("k1","1111");String s1 = commands.get("k1");System.out.println("String s ==="+s1);//listcommands.lpush("myList2", "v1","v2","v3");List<String> list2 = commands.lrange("myList2", 0, -1);for(String s : list2) {System.out.println("list ssss==="+s);}//setcommands.sadd("mySet2", "v1","v2","v3");Set<String> set = commands.smembers("mySet2");for(String s : set) {System.out.println("set ssss==="+s);}//hashMap<String,String> map = new HashMap<>();map.put("k1","138xxxxxxxx");map.put("k2","atguigu");map.put("k3","zzyybs@126.com");//课后有问题请给我发邮件commands.hmset("myHash2", map);Map<String,String> retMap = commands.hgetall("myHash2");for(String k : retMap.keySet()) {System.out.println("hash  k="+k+" , v=="+retMap.get(k));}//zsetcommands.zadd("myZset2", 100.0,"s1",110.0,"s2",90.0,"s3");List<String> list3 = commands.zrange("myZset2",0,10);for(String s : list3) {System.out.println("zset ssss==="+s);}//sortSortArgs sortArgs = new SortArgs();sortArgs.alpha();sortArgs.desc();List<String> list4 = commands.sort("myList2",sortArgs);for(String s : list4) {System.out.println("sort ssss==="+s);}//关闭conn.close();client.shutdown();}
}

集成RedisTemplate(推荐使用

连接单机

1、pom.xml

<!--SpringBoot与Redis整合依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、yaml

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

3、Redis配置

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) "\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*/@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;}
}

4、Service

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;@Service
@Slf4j
public class OrderService
{public static final String ORDER_KEY = "order:";@Resourceprivate RedisTemplate redisTemplate;public void addOrder(){int keyId = ThreadLocalRandom.current().nextInt(1000)+1;String orderNo = UUID.randomUUID().toString();redisTemplate.opsForValue().set(ORDER_KEY+keyId,"京东订单"+ orderNo);log.info("=====>编号"+keyId+"的订单流水生成:{}",orderNo);}public String getOrderById(Integer id){return (String)redisTemplate.opsForValue().get(ORDER_KEY + id);}
}

5、Controller

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.concurrent.ThreadLocalRandom;@Api(tags = "订单接口")
@RestController
@Slf4j
public class OrderController
{@Resourceprivate OrderService orderService;@ApiOperation("新增订单")@RequestMapping(value = "/order/add",method = RequestMethod.POST)public void addOrder(){orderService.addOrder();}@ApiOperation("按orderId查订单信息")@RequestMapping(value = "/order/{id}", method = RequestMethod.GET)public String findUserById(@PathVariable Integer id){return orderService.getOrderById(id);}
}

6、测试

存结果后,出现反序列化问题

原因:JDK序列化方式(默认)惹的祸

org.springframework.data.redis.serializer.JdkSerializationRedisSerializer ,

默认情况下,RedisTemplate 使用该数据列化方式,我们来看下源码 RedisTemplate#afterPropertiesSet()

 解决方式:使用StringRedisTemplate

连接集群

yaml文件

# ========================redis集群=====================
spring.redis.password=111111
# 获取失败 最大重定向次数
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.111.175:6381,192.168.111.175:6382,192.168.111.172:6383,192.168.111.172:6384,192.168.111.174:6385,192.168.111.174:6386

集群存在的问题:

1、模拟节点下线:人为模拟,master-6381机器意外宕机,手动shutdown,先对redis集群命令方式,手动验证各种读写命令,6384上位替换原主节点6381。

原因:Redis Cluster集群能自动感知并自动完成主备切换,对应的slave6384会被选举为新的master节点。

2、出现经典故障:SpringBoot客户端不会动态感知到RedisCluster的最新集群信息

【故障演练】 Redis Cluster集群部署采用了3主3从拓扑结构,数据读写访问master节点, slave节点负责备份。当master宕机主从切换成功,redis手动OK,but 2个经典故障

3、导致原因

SpringBoot2.X版本,Redis默认的连接池采用Lettuce,当Redis集群节点发生变化后,Lettuce默认是不会刷新节点拓扑。

4、解决方案

  • 排除lettuce采用jedis(不推荐)

 

  • 重写连接工厂实例(极度不推荐)
@Beanpublic DefaultClientResources lettuceClientResources() {return DefaultClientResources.create();}@Beanpublic LettuceConnectionFactory lettuceConnectionFactory(RedisProperties redisProperties, ClientResources clientResources) {ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder().enablePeriodicRefresh(Duration.ofSeconds(30)) //按照周期刷新拓扑.enableAllAdaptiveRefreshTriggers() //根据事件刷新拓扑.build();ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()//redis命令超时时间,超时后才会使用新的拓扑信息重新建立连接.timeoutOptions(TimeoutOptions.enabled(Duration.ofSeconds(10))).topologyRefreshOptions(topologyRefreshOptions).build();LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder().clientResources(clientResources).clientOptions(clusterClientOptions).build();RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());clusterConfig.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());clusterConfig.setPassword(RedisPassword.of(redisProperties.getPassword()));LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(clusterConfig, clientConfiguration);return lettuceConnectionFactory;}
  • 刷新节点集群拓扑动态感应

官网:Redis Cluster · lettuce-io/lettuce-core Wiki · GitHub

改写yaml

# ========================redis集群=====================
spring.redis.password=111111
# 获取失败 最大重定向次数
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
#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
spring.redis.lettuce.cluster.refresh.adaptive=true
#定时刷新
spring.redis.lettuce.cluster.refresh.period=2000
spring.redis.cluster.nodes=192.168.111.175:6381,192.168.111.175:6382,192.168.111.172:6383,192.168.111.172:6384,192.168.111.174:6385,192.168.111.174:6386

相关文章:

SpringBoot 集成 Redis

本地Java连接Redis常见问题&#xff1a; bind配置请注释掉保护模式设置为noLinux系统的防火墙设置redis服务器的IP地址和密码是否正确忘记写访问redis的服务端口号和auth密码 集成Jedis jedis是什么 Jedis Client是Redis官网推荐的一个面向java客户端&#xff0c;库文件实现…...

黑客学习笔记(网络安全)

一、首先&#xff0c;什么是黑客&#xff1f; 黑客泛指IT技术主攻渗透窃取攻击技术的电脑高手&#xff0c;现阶段黑客所需要掌握的远远不止这些。 以前是完全涉及黑灰产业的反派角色&#xff0c;现在大体指精通各种网络技术的程序人员 二、为什么要学习黑客技术&#xff1f;…...

[openCV]基于拟合中线的智能车巡线方案V1

import cv2 as cv import os import numpy as np# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表"""newDir d…...

MyBatis-Plus 和达梦数据库实现高效数据持久化

一、添加依赖 首先&#xff0c;我们需要在项目的 pom.xml 文件中添加 MyBatis-Plus 和达梦数据库的依赖&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifac…...

已注销【888】

元神密码 - 飞书云文档 (feishu.cn)...

Ceph错误汇总

title: “Ceph错误汇总” date: “2020-05-14” categories: - “技术” tags: - “Ceph” - “错误汇总” toc: false original: true draft: true Ceph错误汇总 1、执行ceph-deploy报错 1.1、错误信息 ➜ ceph-deploy Traceback (most recent call last):File "/us…...

DataTable过滤某些数据

要过滤DataTable中的某些数据&#xff0c;可以使用以下方法&#xff1a; 使用Select方法&#xff1a;可以使用DataTable的Select方法来筛选满足指定条件的数据行。该方法接受一个字符串参数作为过滤条件&#xff0c;返回一个符合条件的数据行数组。 DataTable filteredTable …...

JAVASE---继承和多态

继承 比如&#xff0c;狗和猫&#xff0c;它们都是一个动物&#xff0c;有共同的特征&#xff0c;我们就可以把这种特征抽取出来。 像这样把相同的可以重新放到一个类里面&#xff0c;进行调用&#xff0c;这就是继承。 概念 继承(inheritance)机制&#xff1a;是面向对象程…...

Centos7升级gcc、g++版本(转载)

Centos7默认的 gcc版本是 4.8.5 默认使用yum install gcc安装出来的gcc版本也是是4.8.5。 1.首先查看自己的 gcc 版本 gcc -v g -v如果出现&#xff1a;bash: g: 未找到命令... 则安装g&#xff1a;遇到暂停时&#xff0c;输入y继续安装 yum install gcc-c然后输入&#xf…...

第一章:继承

系列文章目录 文章目录 系列文章目录前言继承的概念及定义继承的概念继承定义定义格式继承关系和访问限定符继承基类成员访问方式的变化 基类和派生类对象赋值转换&#xff08;公有继承&#xff09;继承中的作用域派生类的默认成员函数继承与友元继承与静态成员不能被继承的类复…...

git面试题

文章目录 git经常用哪些指令git出现代码冲突怎么解决你们团队是怎么管理git分支的如何实现Git的免密操作 git经常用哪些指令 产生代码库 新建一个git代码库 git init下载远程项目和它的整个代码历史 git clone 远程仓库地址配置 显示配置 git config --list [--global]编辑配置…...

Github Copilot在JetBrains软件中登录Github失败的解决方案

背景 我在成功通过了Github Copilot的学生认证之后&#xff0c;在VS Code和PyCharm中安装了Github Copilot插件&#xff0c;但在PyCharm中插件出现了问题&#xff0c;在登录Github时会一直Retrieving Github Device Code&#xff0c;最终登录失败。 我尝试了网上修改DNS&…...

使用 github 同步谷歌浏览器书签

想必使用谷歌浏览器Chrome的用户一定非常头疼的一件事就是&#xff1a;账户不能登录&#xff0c;书签收藏夹不能同步&#xff0c;换一台电脑书签收藏夹没有了&#xff01; 下面教大家一招亲测有效适用的方法解决书签同步问题&#xff0c;在任何电脑都可以同步了 1、去下载谷歌…...

Eclipse进行debug

目录 基本步骤三种执行方式 -- 键盘快捷键variables面板移除debug过的项目通过eclipse调用具有软件界面的项目进行debug各个variable颜色具有的意义 基本步骤 点击eclipse右上角debug按钮 调出debug面板 点击小蜘蛛图标&#xff08;不是点绿色三角的Run&#xff09; 此时会进…...

13-5_Qt 5.9 C++开发指南_基于信号量的线程同步_Semaphore

文章目录 1. 信号量的原理2. 双缓冲区数据采集和读取线程类设计3. QThreadDAQ和QThreadShow 的使用4. 源码4.1 可视化UI设计框架4.2 qmythread.h4.3 qmythread.cpp4.4 dialog.h4.5 dialog.cpp 1. 信号量的原理 信号量(Semaphore)是另一种限制对共享资源进行访问的线程同步机制…...

golang使用泛型实现mapreduce操作

1.使用面向对象的方式写 package streamimport ("fmt""log""reflect""sort""strconv""strings" )type Stream[T any] struct {data []TkeyBy stringsortByNum stringsortByStr []string }func FromElem…...

2023华数杯数学建模C题思路分析 - 母亲身心健康对婴儿成长的影响

# 1 赛题 C 题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c; 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况&#xff0c;如抑郁、焦虑、 压力等&#xff0c;可能会对婴儿的认知、情…...

【汇总】解决Ajax请求后端接口,返回ModelAndView页面不跳转

【汇总】解决Ajax请求后端接口&#xff0c;返回ModelAndView不跳转 问题发现问题解决方法一&#xff1a;直接跳转到指定URL&#xff08;推荐&#xff09;方法二&#xff1a;将返回的html内容&#xff0c;插入到页面某个元素中方法三&#xff1a;操作文档流方法四&#xff1a;使…...

网络安全进阶学习第九课——SQL注入介绍

文章目录 一、什么是注入二、什么是SQL注入三、SQL注入产生的原因四、SQL注入的危害五、SQL注入在渗透中的利用1、绕过登录验证&#xff1a;使用万能密码登录网站后台等。2、获取敏感数据3、文件系统操作4、注册表操作5、执行系统命令 六、如何挖掘SQL注入1、SQL注入漏洞分类按…...

一个计算机专业的学生数据结构这门课学到什么程度才能算学的还不错?

数据结构之所以重要是因为它处于算法中的基础地位&#xff0c;与解决实际问题关系密切&#xff1b;而之所以不重要是因为课本上能学到的所有实现都已经有人造过轮子了&#xff0c;甚至已经作为很多语言的标准API存在了。 换句话来说&#xff0c;在以后的编码生涯中&#xff0c…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...