填坑之路-记录Redis操作的异常QueryTimeoutException RedisCommandTimeoutException: Command timed out after 1 min

本文主要是介绍填坑之路-记录Redis操作的异常QueryTimeoutException RedisCommandTimeoutException: Command timed out after 1 min,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

默认配置

1.命令执行的默认超时时间为1分钟
2.默认的Lettuce集群配置里面才有命令执行超时时间,源码请看:LettuceConnectionFactory
3.修改命令超时时间,请手动修改配置构造器中的配置:LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder 中的setCommandTime

原始异常信息如下

org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:70)at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41)at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:269)at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.convertLettuceAccessException(LettuceStringCommands.java:799)at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.get(LettuceStringCommands.java:68)at org.springframework.data.redis.connection.DefaultedRedisConnection.get(DefaultedRedisConnection.java:260)at org.springframework.data.redis.core.DefaultValueOperations$1.inRedis(DefaultValueOperations.java:57)at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:60)at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:228)at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:188)at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:96)at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:53)at com.vevor.crm.service.base.DictBizServiceImpl.getDictList(DictBizServiceImpl.java:240)at com.vevor.crm.service.base.DictBizServiceImpl.getKey(DictBizServiceImpl.java:145)at com.vevor.crm.task.walmart.WalmartProductTask.convertToCommonProduct(WalmartProductTask.java:107)at com.vevor.crm.task.walmart.WalmartProductTask.pullWalmartProduct(WalmartProductTask.java:85)at com.vevor.crm.task.AllTaskServiceImpl.pullWalmartProduct(AllTaskServiceImpl.java:452)at com.vevor.crm.task.AllTaskServiceImpl$$FastClassBySpringCGLIB$$28033197.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)at org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspect.traceBackgroundThread(TraceAsyncAspect.java:67)at sun.reflect.GeneratedMethodAccessor273.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at org.springframework.cloud.sleuth.instrument.async.TraceRunnable.run(TraceRunnable.java:67)at java.lang.Thread.run(Thread.java:748)
Caused by: io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)at io.lettuce.core.ExceptionFactory.createTimeoutException(ExceptionFactory.java:51)at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:114)at io.lettuce.core.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:69)at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80)at com.sun.proxy.$Proxy440.get(Unknown Source)at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.get(LettuceStringCommands.java:66)... 34 common frames omitted

问题定位,三连击

什么是:QueryTimeoutException
什么是:RedisCommandTimeoutException
为什么百度都说换成Jedis

个人理解:
Redis命令执行超时了而已;

Redis超时的分类

Redis命令超时分为客户端超时和服务端超时。

1.客户端超时时间一般由客户端代码自行控制,业务侧需要根据自己的业务特点选择合适的超时时间(例如Java的Lettuce客户端,该参数名为timeout)。
2.Redis服务端Timeout默认配置为0,不会主动断开连接

开始定位超时问题

1.将Redis配置加入bootstrap.yml文件中
在这里插入图片描述
想要看属性请按住:ctrl+鼠标左键;即可进入对应的类中
2.找到超时的配置属性:timeout
在这里插入图片描述
3.随手一个测试代码,多线程的

@PostConstructpublic void test() {List<String> dataList = new ArrayList<>(1000);for (int i = 0; i < 1000; i++) {dataList.add("testStr:" + i);}// 线程池,多线程执行BlockingQueue<Runnable> threads = new ArrayBlockingQueue<Runnable>(1000);ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 300L, TimeUnit.SECONDS, threads);for (int i = 0; i < 1000; i++) {String key = "key" + i;threadPoolExecutor.execute(() -> {System.out.println("操作" + key);redisTemplate.opsForSet().add(key, dataList);System.out.println(redisTemplate.opsForSet().members(key));});}System.out.println("done");}

4.执行结果统计
4.1.第一把执行
没有任何错误,贼快!
在这里插入图片描述
4.2.觉得和预期不一样,确认有无配置成功
在这里插入图片描述
跟进一下代码,发现是给Redis建立链接的时候用的
在这里插入图片描述
仔细看下代码,发现这个timeout时间压根没用
在这里插入图片描述
我用的是Lettuce连接池,结果发现这玩意压根没有用timeout的配置,搞毛线!
在这里插入图片描述
在这里插入图片描述
4.3.没辙了,只好根据日志提示信息翻过来找

Caused by: io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)at io.lettuce.core.ExceptionFactory.createTimeoutException(ExceptionFactory.java:51)at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:114)at io.lettuce.core.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:69)at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80)at com.sun.proxy.$Proxy440.get(Unknown Source)at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.get(LettuceStringCommands.java:66)... 34 common frames omitted

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
终于发现报错的地方的!居然是获取链接的地方挂了,链接类型:LettuceConnection
在这里插入图片描述
返现Lettuce里面有超时配置,但是这个到底是链接超时的还是命令执行超时呢,还不清楚:
在这里插入图片描述
好好翻一下链接的工厂类,发现了配置项,咱搜一下timeout的作用!
在这里插入图片描述
狐狸尾巴漏出来了,找到了commandTimeout
在这里插入图片描述
在这里插入图片描述
依旧没有发现是能配置的地方,开始思考自己的配置是否正确了;感觉自己没按照正常的配置来了
继续检查我的配置,开始翻看配置的构造了
在这里插入图片描述
4.4.终于发现了,配置的隐藏位置:
在这里插入图片描述

最后修改

一下是我自己的链接工厂配置

        /* ========= 连接池通用配置 ========= */GenericObjectPoolConfig<Object> genericObjectPoolConfig = new GenericObjectPoolConfig<>();genericObjectPoolConfig.setMaxTotal(maxActive);genericObjectPoolConfig.setMinIdle(minIdle);genericObjectPoolConfig.setMaxIdle(maxIdle);genericObjectPoolConfig.setMaxWaitMillis(maxWait);/* ========= lettuce pool ========= */LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();builder.poolConfig(genericObjectPoolConfig);// 这才是最关键的一段builder.commandTimeout(Duration.ofMillis(commandTimeout));LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration, builder.build());connectionFactory.setDatabase(database);connectionFactory.afterPropertiesSet();

这个位置增加一下命令执行时间就好,你想让多久命令超时就多久超时!
根本原因有两个:
1.Redis大key,高频搜,偶发性的报错;
2.value存的大,导致搜索的时候数据返回慢;可自行用RedisDesktopManager查看存的内容大小!
总结:
redis本身很快,但是不规范的使用会导致各种异常; 百度的资料有些让切换Jedis,但是这个改造成本不觉得有点大嘛!

这篇关于填坑之路-记录Redis操作的异常QueryTimeoutException RedisCommandTimeoutException: Command timed out after 1 min的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复

Java空指针异常NullPointerException的原因与解决方案

《Java空指针异常NullPointerException的原因与解决方案》在Java开发中,NullPointerException(空指针异常)是最常见的运行时异常之一,通常发生在程序尝试访问或... 目录一、空指针异常产生的原因1. 变量未初始化2. 对象引用被显式置为null3. 方法返回null

Python使用Code2flow将代码转化为流程图的操作教程

《Python使用Code2flow将代码转化为流程图的操作教程》Code2flow是一款开源工具,能够将代码自动转换为流程图,该工具对于代码审查、调试和理解大型代码库非常有用,在这篇博客中,我们将深... 目录引言1nVflRA、为什么选择 Code2flow?2、安装 Code2flow3、基本功能演示

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

Redis指南及6.2.x版本安装过程

《Redis指南及6.2.x版本安装过程》Redis是完全开源免费的,遵守BSD协议,是一个高性能(NOSQL)的key-value数据库,Redis是一个开源的使用ANSIC语言编写、支持网络、... 目录概述Redis特点Redis应用场景缓存缓存分布式会话分布式锁社交网络最新列表Redis各版本介绍旧

Java如何从Redis中批量读取数据

《Java如何从Redis中批量读取数据》:本文主要介绍Java如何从Redis中批量读取数据的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一.背景概述二.分析与实现三.发现问题与屡次改进3.1.QPS过高而且波动很大3.2.程序中断,抛异常3.3.内存消

Redis中的Lettuce使用详解

《Redis中的Lettuce使用详解》Lettuce是一个高级的、线程安全的Redis客户端,用于与Redis数据库交互,Lettuce是一个功能强大、使用方便的Redis客户端,适用于各种规模的J... 目录简介特点连接池连接池特点连接池管理连接池优势连接池配置参数监控常用监控工具通过JMX监控通过Pr

apache的commons-pool2原理与使用实践记录

《apache的commons-pool2原理与使用实践记录》ApacheCommonsPool2是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能,这篇文章主... 目录一、核心原理与组件二、使用步骤详解(以数据库连接池为例)三、高级配置与优化四、典型应用场景五、注意事

SpringBoot实现文件记录日志及日志文件自动归档和压缩

《SpringBoot实现文件记录日志及日志文件自动归档和压缩》Logback是Java日志框架,通过Logger收集日志并经Appender输出至控制台、文件等,SpringBoot配置logbac... 目录1、什么是Logback2、SpringBoot实现文件记录日志,日志文件自动归档和压缩2.1、