springboot整合redis一直报远程主机强迫关闭了一个现有的连接

在Spring Boot项目中整合Redis时,遇到“远程主机强迫关闭了一个现有的连接”问题,这是一个比较常见的问题,通常涉及网络连接、Redis配置以及客户端设置等方面。本文将详细探讨可能的原因和解决方案,并深入解释Redis的相关配置。

问题描述

在Spring Boot应用中,与Redis交互时经常报以下错误:

2024-04-28 06:54:20 - INFO - [oEventLoop-4-7] io.lettuce.core.protocol.CommandHandler .          log 219 : null Unexpected exception during request: java.io.IOException: 远程主机强迫关闭了一个现有的连接。

java.io.IOException: 远程主机强迫关闭了一个现有的连接。
	at sun.nio.ch.SocketDispatcher.read0(Native Method) ~[na:1.8.0_201]
	at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43) ~[na:1.8.0_201]
	at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[na:1.8.0_201]
	at sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[na:1.8.0_201]
	at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ~[na:1.8.0_201]
	at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:247) ~[netty-buffer-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1147) ~[netty-buffer-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148) ~[netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:700) [netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635) [netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552) [netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514) [netty-transport-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1050) [netty-common-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.43.Final.jar:4.1.43.Final]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.43.Final.jar:4.1.43.Final]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_201]

可能原因分析

  1. 网络问题:网络不稳定或网络配置问题,如防火墙、路由器配置错误等。
  2. Redis服务器配置问题:Redis服务器的timeout和tcp-keepalive设置不当。
  3. 客户端连接设置问题:Spring Boot项目中Redis客户端的配置不当。

解决方案

1. 修改Redis配置文件

需要检查并修改Redis的配置文件(通常是redis.conf)中关于连接超时和TCP保持连接的设置。

timeout 设置

timeout配置项用于设置客户端空闲多长时间后关闭连接(0表示禁用)。如果这个值设置得太低,可能会导致连接被意外关闭。

# Close the connection after a client is idle for N seconds (0 to disable)
timeout 0
tcp-keepalive 设置

tcp-keepalive用于设置TCP保持连接的时间间隔,以便在网络空闲时保持连接活跃。

# 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) Force network equipment in the middle to consider the connection to be
#    alive.
#
# 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 300 seconds, which is the new
# Redis default starting with Redis 3.2.1.
tcp-keepalive 300
配置解释
  1. timeout:当客户端在指定的秒数内没有任何通信时,Redis服务器将关闭该连接。设置为0表示禁用这个超时机制。
  2. tcp-keepalive:在没有通信的情况下,Redis服务器每隔指定的秒数发送一个TCP ACK(确认)数据包给客户端,以保持连接的活跃状态。这不仅能检测到死连接,还能防止中间的网络设备关闭连接。

2. 检查并配置Spring Boot中的Redis客户端

在Spring Boot项目中,使用LettuceJedis作为Redis客户端时,配置不当也可能导致连接问题。需要在application.propertiesapplication.yml中配置Redis客户端的连接池和超时设置。

示例配置(application.properties)
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.timeout=6000
spring.redis.lettuce.pool.max-active=10
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.min-idle=2
spring.redis.lettuce.pool.max-wait=3000
示例配置(application.yml)
spring:
  redis:
    host: localhost
    port: 6379
    timeout: 6000ms
    lettuce:
      pool:
        max-active: 10
        max-idle: 10
        min-idle: 2
        max-wait: 3000ms

3. 检查网络配置

确保防火墙和网络设备没有阻止Redis服务器的端口(默认6379)。可以使用以下命令测试端口连通性:

telnet <redis_host> 6379

如果防火墙阻止了端口,可以使用以下命令打开端口(以CentOS为例):

firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload

4. 其他优化建议

  1. 增加连接池大小:根据应用需求调整连接池的大小,防止连接耗尽。
  2. 启用连接重试机制:在客户端配置中启用连接重试机制,保证在网络抖动时能够重新连接。

总结

通过合理配置Redis服务器和客户端的连接设置,可以有效解决“远程主机强迫关闭了一个现有的连接”问题。关键在于正确配置timeouttcp-keepalive参数,同时确保网络环境的稳定性和客户端的连接设置。

希望通过本文的详细讲解,能帮助你解决Spring Boot整合Redis时遇到的连接问题。如果还有其他疑问或问题,欢迎进一步探讨。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值