Redis Connection reset by peer 异常的懒人解法

最近在使用 Lettuce 集成 Redis 的过程中遇到了一些问题,主要的表现是在测试环境使用正常,但是生产环境中 redis 会出现 Connection reset by peer 的异常。

基础环境 SpringBoot + Lettuce

Redis exception; nested exception is io.lettuce.core.RedisException

org.springframework.data.redis.RedisSystemException: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: Connection reset by peer
        at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:74)
        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:277)
        at org.springframework.data.redis.connection.lettuce.LettuceConnection.await(LettuceConnection.java:1085)
        at org.springframework.data.redis.connection.lettuce.LettuceConnection.lambda$doInvoke$4(LettuceConnection.java:938)
        at org.springframework.data.redis.connection.lettuce.LettuceInvoker$Synchronizer.invoke(LettuceInvoker.java:673)
        at org.springframework.data.redis.connection.lettuce.LettuceInvoker$DefaultSingleInvocationSpec.get(LettuceInvoker.java:589)
        at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.setEx(LettuceStringCommands.java:167)
        at org.springframework.data.redis.connection.DefaultedRedisConnection.setEx(DefaultedRedisConnection.java:335)
        at org.springframework.data.redis.core.DefaultValueOperations$8.potentiallyUsePsetEx(DefaultValueOperations.java:337)
        at org.springframework.data.redis.core.DefaultValueOperations$8.doInRedis(DefaultValueOperations.java:330)
        at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224)
        at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191)
        at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:97)
        at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:325)

java.io.IOException: Connection reset by peer

Caused by: io.lettuce.core.RedisException: java.io.IOException: Connection reset by peer
        at io.lettuce.core.internal.Exceptions.bubble(Exceptions.java:83)
        at io.lettuce.core.internal.Futures.awaitOrCancel(Futures.java:250)
        at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:74)
        at org.springframework.data.redis.connection.lettuce.LettuceConnection.await(LettuceConnection.java:1083)
        ... 75 common frames omitted
Caused by: java.io.IOException: Connection reset by peer
        at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
        at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
        at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
        at sun.nio.ch.IOUtil.read(IOUtil.java:192)
        at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
        at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:256)
        at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132)
        at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:357)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        ... 1 common frames omitted

last destination | Reconnected to

Reconnecting, last destination was /10.1.2.3:26381
Reconnected to 10.1.2.4:26381

如果redis服务本身没有问题,存在java.io.IOException: Connection reset by peer 、Reconnecting, last destination,而且是很有规律的出现,基本上可以断定是 redis 连接双方的 keepalive 机制被某种原因破坏导致的。

根本原因需要通过网络抓包来深入的分析,需要的一定的网络知识,对整理链路的请求转发路径需要比较清楚。

这里介绍一直懒人解法:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.stereotype.Component;


@Component
public class InitializinConfig  implements InitializingBean {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
    
    /**
     * @see org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.SharedConnection#getConnection()
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        if(redisConnectionFactory instanceof LettuceConnectionFactory){
            LettuceConnectionFactory lettuceConnectionFactory = (LettuceConnectionFactory)redisConnectionFactory;
            lettuceConnectionFactory.setValidateConnection(true);
        }
    }

}

通过上面的代码可以每次获取连接前都对连接进行检查,如果连接不可用就重新创建连接,从而避免 Redis Connection reset by peer 的问题。

感兴趣的同学可以去 org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.SharedConnection#getConnection() 这里去翻翻官方的源代码。

希望这个能帮助你解决问题。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
redis connection reset by peer是指在与Redis服务器建立连接时,连接被对方重置或关闭。这种情况通常发生在网络连接不稳定或Redis服务器出现问题时。下面是一些可能导致此错误的原因和解决方法: 1. 网络问题:检查网络连接是否正常,确保网络稳定。可以尝试使用ping命令测试与Redis服务器的连接是否正常。 2. Redis服务器问题:检查Redis服务器是否正常运行。可以尝试使用redis-cli命令连接到Redis服务器并执行一些操作,以确保服务器正常工作。 3. 防火墙问题:如果您的系统上有防火墙,可能会阻止与Redis服务器的连接。请确保防火墙允许与Redis服务器的通信。 4. 连接超时:如果连接超时时间设置得太短,可能会导致连接被重置。可以尝试增加连接超时时间。 5. Redis服务器负载过高:如果Redis服务器负载过高,可能会导致连接被重置。可以尝试优化Redis服务器的配置,以减轻负载。 6. Redis密码错误:如果连接Redis服务器时提供的密码不正确,可能会导致连接被重置。请确保提供正确的密码。 7. Redis版本不兼容:如果您的应用程序使用的Redis客户端与Redis服务器版本不兼容,可能会导致连接被重置。请确保使用兼容的Redis客户端版本。 8. 其他问题:如果以上方法都无法解决问题,可能需要进一步检查Redis服务器和应用程序的配置,以查找其他可能的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值