Springboot集成Redis常见的报错和解决方案

news2025/3/14 12:49:58

Springboot集成Redis后运行时常见的报错信息和其解决方案

  • 1. io.lettuce.core.protocol.CommandHandler : null Unexpected exception during request: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
    • 报错信息
    • 原因分析
    • 解决方案
  • 2. io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 1073741824, max: 1073741824)
    • 报错信息
    • 原因分析
    • 解决方案

1. io.lettuce.core.protocol.CommandHandler : null Unexpected exception during request: java.io.IOException: 远程主机强迫关闭了一个现有的连接。

报错信息

during request: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
项目时基于若依框架开发,在生产环境报错:

io.lettuce.core.protocol.CommandHandler : null Unexpected exception
during request: java.io.IOException: 远程主机强迫关闭了一个现有的连接。

详细日志信息如下:

INFO 3352 --- [ioEventLoop-4-1] io.lettuce.core.protocol.CommandHandler  : null Unexpected exception during request: java.io.IOException: 远程主机强迫关闭了一个现有的连接。

java.io.IOException: 远程主机强迫关闭了一个现有的连接。
	at sun.nio.ch.SocketDispatcher.read0(Native Method) ~[na:1.8.0_221]
	at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43) ~[na:1.8.0_221]
	at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[na:1.8.0_221]
	at sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[na:1.8.0_221]
	at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ~[na:1.8.0_221]
	at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253) ~[netty-buffer-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132) ~[netty-buffer-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350) ~[netty-transport-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151) ~[netty-transport-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) [netty-transport-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) [netty-transport-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) [netty-transport-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) [netty-transport-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) [netty-common-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.69.Final.jar!/:4.1.69.Final]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.69.Final.jar!/:4.1.69.Final]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_221]
	2023-06-14 00:52:16.956  INFO 3352 --- [ionShutdownHook] org.quartz.core.QuartzScheduler          : Scheduler TaskScheduler_$_iZj575z0jja92rZ1686469913890 paused.
	2023-06-14 00:52:16.985  INFO 3352 --- [xecutorLoop-1-8] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was /172.17.151.173:6379

原因分析

日志中容易看出报错信息与redis有关,并且springboot 使用 lettuce做redis 的连接池,lettuce 调用netty与redis服务器通讯

在gitee上找到了若依框架的相同问题,并且官方对于此问题给出了修改方案
在这里插入图片描述

解决方案

  1. 修改配置文件redis.windows.conf的timeout参数
    在这里插入图片描述
Close the connection after a client is idle for N seconds (0 to disable)
在客户端空闲N秒后关闭连接(0表示禁用)

在这里插入图片描述
2. 检查spring项目中redis的配置

redis:
   # 地址
   host: 192.168.0.1
   # 端口,默认为6379
   port: 6379
   # 数据库索引
   database: 10
   # 密码
   password: 147258
   # 连接超时时间 60s
   timeout: 60s
   lettuce:
     pool:
       # 连接池中的最小空闲连接 
       min-idle: 10
       # 连接池中的最大空闲连接 
       max-idle: 30
       # 连接池的最大数据库连接数
       max-active: 8
       # #连接池最大阻塞等待时间(使用负值表示没有限制)
       max-wait: -1ms

3.redis.windows.conf中设置tcp-keepalive时间为60s

# TCP keepalive.
#
# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
# of communication. This is useful for two reasons:
#
# 1) Detect dead peers.
# 2) Take the connection alive from the point of view of network
#    equipment in the middle.
#
# On Linux, the specified value (in seconds) is the period used to send ACKs.
# Note that to close the connection the double of the time is needed.
# On other kernels the period depends on the kernel configuration.
#
# A reasonable value for this option is 60 seconds.
tcp-keepalive 60

配置完成后重启redis服务

2. io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 1073741824, max: 1073741824)

报错信息

io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 1073741824, max: 1073741824)
    at io.netty.util.internal.PlatformDependent.incrementMemoryCounter(PlatformDependent.java:802) ~[netty-common-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(PlatformDependent.java:731) ~[netty-common-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.PoolArena$DirectArena.allocateDirect(PoolArena.java:648) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.PoolArena$DirectArena.newChunk(PoolArena.java:623) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.PoolArena.allocateNormal(PoolArena.java:202) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.PoolArena.tcacheAllocateSmall(PoolArena.java:172) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.PoolArena.allocate(PoolArena.java:134) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.PoolArena.allocate(PoolArena.java:126) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:395) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:188) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:179) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:116) ~[netty-buffer-4.1.72.Final.jar:4.1.72.Final]
    ...

原因分析

当前引入的依赖pom.xml

<!-- redis 缓存操作 -->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>

Springboot2.x以后弃用jedis改为使用lettuce作为操作redis数据库的客户端,而Lettuce使用的 netty 框架,引用的netty包netty-common-4.1.49.Final.jarPlatformDependent.java类 中的incrementMemoryCounter方法。该方法判断堆外内存是否大于当前服务可使用的内存,是则抛出throw new OutOfDirectMemoryError。因此该问题的发生是Spring对Lettuce的支持不够好,还存在问题。

 private static void incrementMemoryCounter(int capacity) {
        if (DIRECT_MEMORY_COUNTER != null) {
            long newUsedMemory = DIRECT_MEMORY_COUNTER.addAndGet(capacity);
            //校验堆外内存是否大于当前服务可使用的内存,如果大于则抛出 OutOfDirectMemoryError(堆外内存溢出)
            if (newUsedMemory > DIRECT_MEMORY_LIMIT) {
                DIRECT_MEMORY_COUNTER.addAndGet(-capacity);
                throw new OutOfDirectMemoryError("failed to allocate " + capacity
                        + " byte(s) of direct memory (used: " + (newUsedMemory - capacity)
                        + ", max: " + DIRECT_MEMORY_LIMIT + ')');
            }
        }
    }

解决方案

  1. 调大堆外内存 -Dio.netty.maxDirectMemory,但是治标不治本
  2. 放弃Lettuce客户端,改回Jedis客户客户端
<!--引入redis,排除lettuce的引用-->
<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>

<!-- 引入Jedis客戶端-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python自动化测试 史上最全的进阶教程

Python自动化测试就是把以前人为测试转化为机器测试的一种过程。自动化测试是一种比手工测试更快获得故障反馈的方法。 随着时代的变革&#xff0c;也许在未来测试这个职位的需求会越来越少甚至消失&#xff0c;但是每一个组织&#xff0c;每一个客户对软件质量的要求是永远不…

剪辑软件生成的mp4素材无法打开的修复方法

专业剪辑软件可以对视频、音频进行各种修改、美化&#xff0c;像adobe的PR等。今天我们来看一个剪辑软件生成的视频无法打开的修复案例&#xff0c;看看遇到这种情况如何处理. 故障文件:273M和1.72G两个文件 故障现象: 剪辑完成后保存到移动硬盘&#xff08;文件系统为exfat…

VALSE 2023 无锡线下参会个人总结 6月10日-1

VALSE2023无锡线下参会个人总结6月10日-1 会场照片6月10日会议日程安排大会主旨报告&#xff1a;高文&#xff1a;特征编码与数字视网膜焦李成&#xff1a;下一代深度学习的思考与若干问题陈熙霖&#xff1a;计算机视觉-从孤立到系统性方法 企业宣讲环节&#xff08;一&#xf…

邓铎:书中自有天地人

邓铎&#xff0c;一个优秀的艺术家&#xff0c;他的书法作品、理论文章自成一派&#xff0c;从书法中咀嚼出人生百味&#xff0c;大千世界&#xff0c;写下了他生命中“六十余载&#xff0c;书中天地人”的执着与坚持。 作为一名优秀的书法家&#xff0c;邓铎的艺术表达具有独…

网安笔记14 firewall

防火墙概述 由软件和硬件组成的系统&#xff0c;它处于安全的网络和不安全的网络之间&#xff0c;根据由系统管理员设置的访问控制规则&#xff0c;对数据流进行过滤 对于内部攻击以及绕过防火墙的连接却无能为力 对数据流如何处理 允许数据流通过拒绝数据流通过&#xff0…

构建工具 Vite、Webpack、Rollup对比

Webpack介绍 热更新方面&#xff1a;webpack支持HMR&#xff0c;但是webpack需要全部重新编译并更新&#xff0c;效率较低 tree-shaking&#xff1a;webpack2开始支持且消除效果不好&#xff0c;但是webpack5有更好的tree-shaking&#xff08;去除未使用代码&#xff09; 分包…

0基础学习VR全景平台篇第43篇:编辑器底部菜单-隐藏场景

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 本期为大家带来蛙色VR平台&#xff0c;底部菜单—隐藏场景功能操作。 功能位置示意 一、本功能将用在哪里&#xff1f; 隐藏场景功能&#xff0c;指将选中的场景隐藏&#xff0c;浏览页将不显示隐藏的…

最详细,从0-1性能测试步骤详细,测试老鸟经验总结...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试流程 性…

sandfly-entropyscan:一款功能强大的恶意程序熵扫描工具

关于sandfly-entropyscan sandfly-entropyscan是一款功能强大的熵扫描工具&#xff0c;该工具可以用于检测与恶意软件相关的打包文件或加密二进制文件。除此之外&#xff0c;该工具还支持查找恶意文件和Linux进程相关的安全信息&#xff0c;并提供带有加密哈希的输出结果。 s…

cesium学习(下载,官方案例)

下载cesium源码 可以从官网直接下载&#xff0c;官网下载的是编译好的。链接: https://www.cesium.com/downloads/从github下载源码&#xff0c;方便我们本地调试学习(本文采用这种方式)。链接: https://github.com/CesiumGS/cesium 运行项目 安装依赖 npm i运行 npm run …

八股|ThreadLocal的内存泄露

ThreadLocal是个好用的工具类&#xff0c;但是使用不好是会导致内存泄露的。 内存泄露&#xff1a;之前开辟使用的内存空间&#xff0c;在使用完毕后未释放&#xff0c;结果导致一直占据该内存单元&#xff0c;无法被gc回收&#xff0c;导致该内存单元后续无法被使用&#xff0…

优思学院|质量管理六大思维陷阱【四】:抽样检查是最经济又能保证质量的方法吗?

在质量控制的过程中&#xff0c;一个常见的误解是认为抽样检查是最经济又能保证质量的方法。许多人认为进行百分之百的全数检查既浪费人力又时间不够。因此&#xff0c;他们倾向于采用抽样检查的方法&#xff0c;认为这样既符合经济成本&#xff0c;又能确保产品质量的水准。 …

Java中的死锁和Lock锁

6.死锁 1.死锁的理解&#xff1a; 不同的线程分别占用对方需要的同步资源不放弃&#xff0c;都在等待对方放弃自己需要的同步资源&#xff0c;就形成了线程的死锁 2.说明&#xff1a; 1出现死锁后&#xff0c;不会出现异常&#xff0c;不会出现提示&#xff0c;只是锁的线程…

【小白入门】Verilog实现异步FIFO

之前也在CSDN上面写过两个FIFO相关的文章&#xff0c;不过代码看起来比较复杂&#xff0c;且注释也比较少&#xff0c;不利于新手入门。很多时候都没有耐心继续看下去。 http://t.csdn.cn/0dPX6 http://t.csdn.cn/lYvoY 因为自己本身是一个初学者&#xff0c;就从初学者的视…

交换排序——冒泡排序和快速排序

一、交换排序的基本思想 1、两两比较&#xff0c;如果发生逆序则交换&#xff0c;直到所有记录都排好序为止。 2、常见的交换排序方法&#xff1a;冒泡排序和快速排序 3、最简单的交换排序——简单选择排序算法描述 void SelectSort(SqList &K) {for (i1; i<L.lengt…

浅谈C++和Java中对象的等号赋值

随着对C学习的深入&#xff0c;发现了一些和Java在设计思想上有所不同的地方。其一就是对象的拷贝赋值。 在Java中&#xff0c;如果定义了两个对象s1和s2&#xff0c;在堆内存中将会创建两个对象实体。那么s1 s2;表示s1指向的对象发生改变&#xff0c;即指向了s2所指向的对象…

8分钟让你完全掌握代理IP基础知识和实际应用

概念 代理IP可以理解为一个中转服务器&#xff0c;将用户和目标服务器之间的请求和响应进行转发和代理。使用代理IP的主要目的是隐藏用户的真实IP地址、访问被限制的内容、提高网络连接速度和保护用户隐私。 目录 概念 一、代理IP的工作原理 二、代理IP的类型 三、为什么…

总结的太到位:python 多线程系列详解

前言&#xff1a; 上vip课的时候每次讲到框架的执行&#xff0c;就会有好学的同学问用多线程怎么执行&#xff0c;然后我每次都会说在测开课程会详细讲解&#xff0c;这并不是套路&#xff0c;因为如果你不理解多线程&#xff0c;不清楚什么时候该用什么时候不该用&#xff0c;…

Clean架构与MVVM:助你打造优质Android应用

Android应用程序开发可能具有挑战性&#xff0c;特别是在创建可扩展和可维护的代码以适应不断变化的需求和用户需求方面。为了解决这个挑战&#xff0c;开发者通常依赖于软件架构模式&#xff0c;为代码组织和关注点分离提供了坚实的基础。在Android开发中&#xff0c;两种流行…

7-基于51单片机的金属探测器检测金属报警器设计(源程序+原理图+PCB+论文)全套资料

编号: 0007 本系统采用单片机1602液晶按键比较器蜂鸣器发光二极管组合而成。 按键说明: 加键、减键。单独一个按键为复位按键 1.单片机型号: STC89C52/51、AT89C52/51、AT89S52/51 可任选&#xff0c;程序通用2.产品自带单片机上电复位电路、手动复位电路(复位按键)、晶振电路(…