成品源码网站永久地址入口进入/云南疫情最新数据消息中高风险地区
背景
springboot使用redisTemplate访问redis cluster(三主三从),底层是Lettuce,当其中一个master挂掉后,slave正常升为master,程序报错 Redis commond timed out after 6 seconds。
解决
手动连接集群,正常读写,确定为应用程序的问题
查看应用程序的redis 集群配置,没有问题
查看网上的解决办法,发现是Lettuce的问题
转载:验证了方案二,把lettuce换成jedis,切换正常
最新一次线上生产环境下Redis集群服务器某一个主节点发生故障,Cluster节点下的从节点快速进行迁移升级为主节点,节点迁移时间大概为15秒,这15秒期间Redis服务不可用,程序无法读写Redis数据,报错java.lang.RuntimeException: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s),但是15秒过后服务依旧无法使用,大概持续了6分钟,而在业务高峰期间这6分钟也会造成很大的用户感知,为何要持续这么久Redis才能恢复,成为了未知的谜团!
联合运维和云厂商做了很多测试,发现凡是使用jedis客户端的服务都可以在15秒主从切换后恢复,而使用lettuce作为redis客户端的服务则无法恢复使用,一直抛超时的异常,做了实验发现,使用lettuce作为客户端的服务,在15秒主从切换后一直要等待redis服务的宕机节点拉起成功后才可以恢复,而这时间大概持续了2分钟,从网上搜了很多答案发现也有一些遇到了同样问题的情况发生。Lettuce的节点切换15秒是来源于 cluster-node-timeout这个配置的默认时间,这个是时间节点宕机发现时间,也就是Redis群集节点不可用的最长时间,因为RedisCluster是无中心设计,节点探测的时间设置太小会因为网络抖动造成的节点下线,时间太长又无法快速处理节点切换,这个可以具体了解Cluster集群主从切换的原理。相关阅读https://www.cnblogs.com/kaleidoscope/p/9636264.html
因为所有微服务使用SpringBoot2.1.7版本SpringBoot2.X版本开始Redis默认的连接池都是采用的Lettuce,之前的文章也有介绍过Lettuce连接池的使用,为了避免后续出现硬件故障,导致服务连接Redis一段时间不可用的情况,所以也就急需要解决节点宕机的恢复时间问题。
经过大量的调研和实验最后发现有关,官方的描述是https://github.com/lettuce-io/lettuce-core/wiki/Redis-Cluster#user-content-refreshing-the-cluster-topology-view, Lettuce需要刷新节点拓扑视图,
大致意思是,Redis集群配置在运行期间可能会改变,可以添加新的节点,为特定插槽的主节点可以发生改变,Lettuce处理Moved和Ask永久重定向,但是由于命令重定向,你必须刷新节点拓扑视图,拓扑是绑定到RedisClusterClient的示例,所有由一个RedisClusterClient实例创建的节点连接共享相同的节点拓扑视图,视图可以采用以下三种方式更新
1、Either by calling RedisClusterClient.reloadPartitions
通过调用RedisClusterClient.reloadPartitions
2、Periodic updates in the background based on an interval
后台基于时间间隔的周期刷新
3、Adaptive updates in the background based on persistent disconnects and MOVED/ASKredirections
后台基于持续的断开和移动/重定向的自适应更新
By default, commands follow -ASK and -MOVED redirects up to 5 times until the command execution is considered to be failed. Background topology updating starts with the first connection obtained through RedisClusterClient.
默认的 命令跟随ASK 和移MOVED 命令执行重定向到5次,直到被认为是失败了,后台拓扑更新始于第一次RedisClusterClient链接
相关阅读 https://github.com/lettuce-io/lettuce-core/wiki/Client-options#periodic-cluster-topology-refresh
所以说在RedisCluster集群模式下可以通过 3种方式去刷新节点拓扑视图去解决节点重新识别的问题,
第一种方式是通过RedisClusterClient,SpringBoot通过Sprint Redis Data构建Redis时,没有显式构建RedisClusterClient,所以只能通过其他两种方式
https://github.com/lettuce-io/lettuce-core/wiki/Client-Options
这里描述了很多特殊场景下设置的客户端选项,可以视自身情况去设置调整
@Autowired private RedisProperties redisProperties; @Bean public GenericObjectPoolConfig<?> genericObjectPoolConfig(Pool properties) { GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>(); config.setMaxTotal(properties.getMaxActive()); config.setMaxIdle(properties.getMaxIdle()); config.setMinIdle(properties.getMinIdle()); if (properties.getTimeBetweenEvictionRuns() !=null) { config.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRuns().toMillis()); } if (properties.getMaxWait() !=null) { config.setMaxWaitMillis(properties.getMaxWait().toMillis()); } return config; } @Bean(destroyMethod ="destroy") public LettuceConnectionFactory lettuceConnectionFactory() { //开启 自适应集群拓扑刷新和周期拓扑刷新 ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder() // 开启全部自适应刷新 .enableAllAdaptiveRefreshTriggers() // 开启自适应刷新,自适应刷新不开启,Redis集群变更时将会导致连接异常 // 自适应刷新超时时间(默认30秒) .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30)) //默认关闭开启后时间为30秒 // 开周期刷新 .enablePeriodicRefresh(Duration.ofSeconds(20)) // 默认关闭开启后时间为60秒 ClusterTopologyRefreshOptions.DEFAULT_REFRESH_PERIOD 60 .enablePeriodicRefresh(Duration.ofSeconds(2)) = .enablePeriodicRefresh().refreshPeriod(Duration.ofSeconds(2)) .build(); // https://github.com/lettuce-io/lettuce-core/wiki/Client-Options ClientOptions clientOptions = ClusterClientOptions.builder() .topologyRefreshOptions(clusterTopologyRefreshOptions) .build(); LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder() .poolConfig(genericObjectPoolConfig(redisProperties.getLettuce().getPool())) //.readFrom(ReadFrom.MASTER_PREFERRED) .clientOptions(clientOptions) .commandTimeout(redisProperties.getTimeout()) //默认RedisURI.DEFAULT_TIMEOUT 60 .build(); List<String> clusterNodes = redisProperties.getCluster().getNodes(); Set<RedisNode> nodes = new HashSet<RedisNode>(); clusterNodes.forEach(address -> nodes.add(new RedisNode(address.split(":")[0].trim(), Integer.valueOf(address.split(":")[1])))); RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration(); clusterConfiguration.setClusterNodes(nodes); clusterConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword())); clusterConfiguration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects()); LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(clusterConfiguration, clientConfig); // lettuceConnectionFactory.setShareNativeConnection(false); //是否允许多个线程操作共用同一个缓存连接,默认true,false时每个操作都将开辟新的连接 // lettuceConnectionFactory.resetConnection(); // 重置底层共享连接, 在接下来的访问时初始化 return lettuceConnectionFactory; }
开启自适应刷新并设定刷新频率
可以看到设定前,周期刷新和拓扑刷新都是false

调整后周期刷新和拓扑刷新都是true

enablePeriodicRefresh意思就是开启并设定周期刷新时间
开关的开启后的控制实际是RedisClusterClient.activateTopologyRefreshIfNeeded在这个方法内完成的,如果开关开启则会创建一个ScheduledFuture 根据你设置的节点刷新事件定期的去调用,当RedisClusterClient初始化后,定时器会周期性的执行,
如果 定时器执行通过,则RedisClusterClient.doLoadPartitions会返回loadedPartitions,如果半截Return掉,则不再返回新的节点信息。


相关阅读https://github.com/lettuce-io/lettuce-core/issues/240
相关阅读https://blog.csdn.net/weixin_42182797/article/details/95210437#_1
当然,如果你想就此放弃lettuce转用jedis也是可以的 Spring Boot2.X版本,只要在pom.xml里,调整一下依赖包的引用
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
配置上lettuce换成jedis的,既可以完成底层对jedis的替换
spring: redis: database: 0 #Redis 索引(0~15,默认为0) timeout: 1000 #Redis 连接的超时时间 password: #Redis 密码,如果没有就默认不配置此参数 cluster: #Redis 集群配置 max-redirects: 5 #Redis 命令执行时最多转发次数 nodes: 192.168.56.15:7000,192.168.56.15:7001,192.168.56.16:7002,192.168.56.16:7003,192.168.56.17:7004,192.168.56.17:7005 #Redis 集群地址 jedis: pool: max-active: 20 max-wait: -1 min-idle: 0 max-idle: 10#使用 lettuce 连接池# lettuce: # pool:# max-active: 20 #连接池最大连接数(使用负值表示没有限制)# max-wait: -1 #连接池最大阻塞等待时间(使用负值表示没有限制)# min-idle: 0 #连接池中的最大空闲连接# max-idle: 10 #连接池中的最小空闲连接
因为jedis的节点信息,没有搞的那么复杂

相关文章:

RedisCluster集群模式下master宕机主从切换期间Lettuce连接Redis无法使用报错Redis command timed out的问题
背景springboot使用redisTemplate访问redis cluster(三主三从),底层是Lettuce,当其中一个master挂掉后,slave正常升为master,程序报错 Redis commond timed out after 6 seconds。解决手动连接集群…...

Xuetr杀毒工具使用实验(28)
实验目的 (1)学习Xuetr的基本功能; (2)掌握Xuetr的基本使用方法。预备知识 windows操作系统的基本知识如:进程、网络、服务和文件等的了解。 XueTr是近年推出的一款广受好评的ARK工具。ARK工具全称为Anti R…...

fastapi(https)+openssl+测试(双向校验)
第一步生成根证书 # Generate CA private key openssl genrsa -out ca.key 2048 # Generate CSR openssl req -new -key ca.key -out ca.csr # Generate Self Signed certificate(CA 根证书) openssl x509 -req -days 365 -in ca.csr -signkey ca.key -o…...

TiDB Server
文章目录TiDB Server架构TiDB Server作用TiDB Server的进程SQL语句的解析和编译SQL读写相关模块在线DDL相关模块GC机制与相关模块TiDB Server的缓存热点小表缓存TiDB Server架构 Protocol Layer、Parse、Compile负责sql语句的解析编译和优化,然后生成sql语句执行计划…...

S3C2440移植Linux4.19.275内核以及过程中遇到的问题
目录 1 问题一:内核移植时MTD分区问题 2 问题二:uboot的MTDPARTS_DEFAULT定义的MTD分区,bootargs中的文件系统分区,内核的mtd_partition smdk_default_nand_part定义的分区,三者要对应起来 3 问题三:ubo…...

解忧杂货铺(二):UML时序图
目录 1、概述 2、UML时序图 2.1、什么是时序图 2.2、时序图的元素 2.2.1 角色(Actor) 2.2.2 对象(Object) 2.2.3 生命线(LifeLine) 2.2.4 控制焦点(Activation) 2.2.5 消息(Message) 2.2.6 自关联消息 2.2.7 组合片段 1、概述 在看AUTOSAR规范的时候发现时序图里面的…...

微信小程序的代码由哪些结构组成?
小程序官方建议把所有小程序的页面,都存放在pages 目录中,以单独的文件夹存在,如图所示: 其中,每个页面由4 个基本文件组成,它们分别是:js文件(页面的脚本文件,存放页面的数据、事件…...

Cloud Kernel SIG月度动态:发布 ANCK 新版本及 Plugsched v1.2.0
Cloud Kernel SIG(Special Interest Group):支撑龙蜥内核版本的研发、发布和服务,提供生产可用的高性价比内核产品。 01 2 月 SIG 整体进展 发布 ANCK 4.19.91-27.1 版本。 发布 ANCK 5.10.134-13.1 版本。 调度器热升级相关事…...

Jedis 使用详解(官方原版)
一、配置 Maven 依赖项Jedis也通过Sonatype作为Maven Dependency 分发。要配置它,只需将以下 XML 代码段添加到您的 pom.xml 文件中。<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.…...

关于Pytorch中的张量学习
关于Pytorch中的张量学习 张量的概念和创建 张量的概念 Tensor是pytorch中非常重要且常见的数据结构,相较于numpy数组,Tensor能加载到GPU中,从而有效地利用GPU进行加速计算。但是普通的Tensor对于构建神经网络还远远不够,我们需…...

基于Transformer的目标检测算法学习记录
前言 本文主要通过阅读相关论文了解当前Transformer在目标检测领域的应用与发展。 谷歌在 ICLR2020 上提出的 ViT(Vision Transformer)是将 Transformer 应用在视觉领域的先驱。从此,打开了Transformer进入CV领域的桥梁,NLP与CV几…...

嵌入式学习笔记——使用寄存器编程实现按键输入功能
文章目录前言模块介绍原理图编程思路前言 昨天,通过配置通用输出模式,实现了LED灯的点亮、熄灭以及流水等操作,解决了通用输出的问题,今天我们再借用最常见的输入模块,按键来实现一个按键控制LED的功能,重…...

打卡小达人之路:Spring Boot与Redis GEO实现商户附近查询
在当今社会,定位服务已经成为了各种应用的重要组成部分,比如地图、打车、美食等应用。如何在应用中实现高效的附近商户搜索功能呢?传统的做法是将商户的经纬度信息存储在关系型数据库中,然后使用SQL查询语句实现附近商户搜索功能。…...

Apache HTTP Server <2.4.56 mod_proxy_uwsgi 模块存在请求走私漏洞(CVE-2023-27522)
漏洞描述 Apache HTTP Server 是一个Web服务器软件。 该项目受影响版本存在请求走私漏洞。由于mod_proxy_uwsgi.c 中uwsgi_response方法对于源响应头缺少检查,当apache启用mod_proxy_uwsgi后,攻击者可利用过长的源响应头等迫使应转发到客户端的响应被截…...

JUC并发编程设计模式
一、保护性暂停 1.1 定义 即Guarded Suspension,用在一个线程等待另一 个线程的执行结果 要点 ● 有一个结果需要从一个线程传递到另一 个线程,让他们关联同一一个GuardedObject ● 如果有结果不断从一个线程到另一个线程那么可以使用消息队列(生产者…...

HTTPS加密解析
日升时奋斗,日落时自省 目录 1、加密解释 2、对称加密 3、非对称加密 4、证书 HTTPS(HyperText Transfer Protocol over Secure Socket Layer)也是一个应用层协议,是在HTTP协议的基础上引入了一个加密层 HTTP协议内容都是按…...

Python每日一练(20230309)
目录 1. 删除有序数组中的重复项 ★ 2. 二叉树的最小深度 ★★ 3. 只出现一次的数字 II ★★ 🌟 每日一练刷题专栏 C/C 每日一练 专栏 Python 每日一练 专栏 1. 删除有序数组中的重复项 给你一个有序数组 nums ,请你原地删除重复出现的元素…...

哈希表题目:数组的度
文章目录题目标题和出处难度题目描述要求示例数据范围解法思路和算法代码复杂度分析题目 标题和出处 标题:数组的度 出处:697. 数组的度 难度 4 级 题目描述 要求 给定一个非空且只包含非负数的整数数组 nums\texttt{nums}nums,数组的…...

初识rollup 打包、配置vue脚手架
rollup javascript 代码打包器,它使用了 es6 新标准代码模块格式。 特点: 面向未来,拥抱 es 新标准,支持标准化模块导入、导出等新语法。tree shaking 静态分析导入的代码。排除未实际引用的内容兼容现有的 commonJS 模块&#…...

软考网络工程师证书有用吗?
当然有用,但是拿到网络工程师证书的前提是对你自己今后的职业发展有帮助,用得到才能对你而言发挥它最大的好处。软考证书的具体用处:1.纳入我国高校人才培养和教学体系目前,软考已经被纳入高校人才培养和教学体系。在很多高校中&a…...

postgresql 自动备份 bat实现
postgres数据据备分,用cmd命令有些烦,写了个bat实现 BAT脚本中常用的注释命令有rem、@rem和:: rem、@rem和::用法都很简单,直接在命令后加上要注释的语句即可。例如下图,语言前加了rem,运行BAT时就会自动忽略这个句子。需要注释多行时,每行前面都要加上rem、@rem和::。…...

gdb:在命令行中会莫名暂停;detach-on-fork
这个没有捕获到断点的原因是,可能是多线程的问题,需要设置: set detach-on-fork off On Linux, if you want to debug both the parent and child processes, use the command: set detach-on-fork on/off on 默认设置,gdb会放弃子线程(或者父线程,受follow-fork-mode的…...

【3.9】RedisAOF日志、字符串、操作系统进程管理
4. 进程管理 进程、线程基础知识 什么是进程 我们编写的代码只是一个存储在硬盘的静态文件,通过编译后就会生成二进制可执行文件,当我们运行这个可执行文件后,它会被装载到内存中,接着 CPU 会执行程序中的每一条指令,…...

安装mayavi的成功步骤
这篇文章是python 3.6版本,windows系统下的安装,其他python版本应该也可以,下载对应的包即可。 一定不要直接pip install mayavi,这个玩意儿对vtk的版本有要求。 下载whl包 搞了很久不行,咱也别费那个劲了࿰…...

vue+echarts.js 实现中国地图——根据数值表示省份的深浅——技能提升
最近在写后台管理系统,遇到一个需求就是 中国地图根据数值 展示深浅颜色。 效果图如下: 直接上代码: 1.html部分 <div id"Map"></div>2.css部分——一定要设置尺寸 #Map {width: 100%;height: 400px; }3.js部分 …...

[oeasy]python0104_指示灯_显示_LED_辉光管_霓虹灯
编码进化 回忆上次内容 x86、arm、riscv等基础架构 都是二进制的包括各种数据、指令 但是我们接触到的东西 都是屏幕显示出来的字符 计算机 显示出来的 一个个具体的字型 计算机中用来展示的字型 究竟是 如何进化的 呢?🤔🤔 模拟电路时…...

Easy Deep Learning——卷积层
为什么需要卷积层,深度学习中的卷积是什么? 在介绍卷积之前,先引入一个场景 假设您在草地上漫步,手里拿着一个尺子,想要测量草地上某些物体的大小,比如一片叶子。但是叶子的形状各异,并且草地非…...

深入分析@Bean源码
文章目录一、源码时序图二、源码解析1. 运行案例程序启动类2. 解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext(Class<?>... componentClasses)构造方法3. 解析AbstractApplicationContext类的refresh()方法4. 解析AbstractApplicationC…...

Web Components学习(1)
一、什么是web components 开发项目的时候为什么不手写原生 JS,而是要用现如今非常流行的前端框架,原因有很多,例如: 良好的生态数据驱动试图模块化组件化等 Web Components 就是为了解决“组件化”而诞生的,它是浏…...

Element-UI实现复杂table表格结构
Element-UI组件el-table用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。将使用到以下两项,来完成今天demo演示:多级表头:数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。合…...