Spring Data Redis JedisConnectionException:流的意外结束 [英] Spring Data Redis JedisConnectionException: Unexpected end of stream

查看:125
本文介绍了Spring Data Redis JedisConnectionException:流的意外结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Redis 3.0.5
Spring Data Redis 1.3.6
杰迪斯2.6.3
-我们的网络应用程序可以通过pub/sub接收来自redis的数据.
-还对Redis上的数据进行键/值对的读/写.
-读/写发生在侦听器线程,独立的监视线程和http请求线程上.
-我们对Listener和Redis模板使用了相同的连接工厂.
-我们的Redis服务器已配置"timeout = 30"

Redis 3.0.5
Spring Data Redis 1.3.6
jedis 2.6.3
- Our is web application which receives data from redis over pub/sub.
- Also performs read/write of data on redis as key/value pairs.
- read/write happens on listener thread, independent monitoring thread and http request threads.
- We have used a same connection factory for Listener and redis template
- Our redis server has "timeout=30" configured

<bean id="jedisConnectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <property name="hostName" value="nnnn"></property>
    <property name="port" value="nnnn"></property>
    <property name="password" value="****"></property>
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
    <property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
<bean id="redisContainer"
    class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
    <property name="connectionFactory" ref="jedisConnectionFactory" />
    <property name="messageListeners">
        <map>
            <entry key-ref="messageListener">
                <bean class="org.springframework.data.redis.listener.ChannelTopic">
                    <constructor-arg value="topic_name" />
                </bean>
            </entry>
        </map>
    </property>
    <property name="taskExecutor" ref="redisTaskExecutor" />
    <property name="subscriptionExecutor" ref="redisSubTaskExecutor" />
</bean>
<bean id="redisTaskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="threadNamePrefix" value="RedisListenerThread"></property>
    <property name="corePoolSize" value="1" />
    <property name="maxPoolSize" value="1" />
</bean>
<bean id="redisSubTaskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="threadNamePrefix" value="RedisSubscribeThread"></property>
    <property name="corePoolSize" value="1" />
    <property name="maxPoolSize" value="1" />
</bean>
<bean id="messageListener"
    class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
    <constructor-arg index="0">
        <bean class="my.data.Receiver" />
    </constructor-arg>
    <constructor-arg index="1"><value>receive</value></constructor-arg>
</bean>

在读取数据的过程中,有时我们在生产上会遇到以下问题.

occasionally we face below problem on production during data read.

org.springframework.data.redis.RedisConnectionFailureException:流的意外结束.嵌套异常是redis.clients.jedis.exceptions.JedisConnectionException:流的意外末尾. 在org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:47) 在org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:36) 在org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:37) 在org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:37) 在org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:182) 在org.springframework.data.redis.connection.jedis.JedisConnection.get(JedisConnection.java:1087) 在org.springframework.data.redis.connection.DefaultStringRedisConnection.get(DefaultStringRedisConnection.java:276) 在org.springframework.data.redis.core.DefaultValueOperations $ 1.inRedis(DefaultValueOperations.java:46) 在org.springframework.data.redis.core.AbstractOperations $ ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:50) 在org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:190) 在org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:152) 在org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:84) 在org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:43)

org.springframework.data.redis.RedisConnectionFailureException: Unexpected end of stream.; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream. at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:47) at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:36) at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:37) at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:37) at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:182) at org.springframework.data.redis.connection.jedis.JedisConnection.get(JedisConnection.java:1087) at org.springframework.data.redis.connection.DefaultStringRedisConnection.get(DefaultStringRedisConnection.java:276) at org.springframework.data.redis.core.DefaultValueOperations$1.inRedis(DefaultValueOperations.java:46) at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:50) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:190) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:152) at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:84) at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:43)

我已经阅读了其他有关使用单线程进行读/写的线程.但是在我们的情况下,很难使用单线程.同样根据RedisTemplate文档,它是线程安全的. 问题偶尔出现,我们无法在任何dev/testing/uat环境中复制.因此无法找到相同的确切原因. 我们做错了什么?

I have read other threads talking of using single thread for read/write. But in our case it is difficult to use single thread. Also as per RedisTemplate documentation, it is thread safe. The problem is occasional and we are unable to reproduce in any of dev/testing/uat environment. Thus unable to find exact cause of the same. What have we done wrong?

推荐答案

我们已经能够重现该问题,原因是Redis中的"timeout = 30"设置.

We have been able to reproduce the issue and the cause is "timeout=30" setting in Redis.

  1. 连接空闲30秒,Redis杀死该连接.
  2. 应用程序中的"Redis连接工厂"检测到损坏之前 连接,它将为读取或写入请求分配
  3. 代码 尝试使用此连接,但由于它已断开,因此无法 发送命令以进行读/写.因此,我们得到"JedisConnectionException: 流意外结束"异常
  1. Connection is idle for 30seconds and Redis kills the same.
  2. Before "Redis connection factory" in application detects the broken connection, it gets allocation for read or write request
  3. Code tries to use this connection but as it is broken, it is unable to send command for read/write. Thus we get "JedisConnectionException: Unexpected end of stream" exception

解决方案

  1. 将Redis超时设置为零
  2. 使用自定义JedisPoolConfig集 将minEvictableIdleTimeMillis设置为所需值.这将确保 空闲连接从Jedis连接池中释放
  1. set Redis timeout to Zero
  2. Using custom JedisPoolConfig set the minEvictableIdleTimeMillis to desired value. This will ensure idle connections are released from Jedis connection pool

这篇关于Spring Data Redis JedisConnectionException:流的意外结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆