redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream. at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:199) at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40) at redis.clients.jedis.Protocol.process(Protocol.java:151) at redis.clients.jedis.Protocol.read(Protocol.java:215) at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340) at redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:259) at redis.clients.jedis.Connection.getBulkReply(Connection.java:248) at redis.clients.jedis.Jedis.get(Jedis.java:153)
看jedis的源码如下:
privatevoidensureFill()throws JedisConnectionException { if (count >= limit) { try { limit = in.read(buf); count = 0; if (limit == -1) { // 这里抛了异常 thrownew JedisConnectionException("Unexpected end of stream."); } } catch (IOException e) { thrownew JedisConnectionException(e); } } }
那我就是写代码模拟一下这种情况,连接暴涨之后,因为回收策略的问题,导致的连接使用的问题,但是我不管怎么配置,都不能模拟出Unexpected end of stream的情况,那我就怀疑到底是不是因为回收的问题,因为上面的回收配置来看,10分钟也释放不了那么多空闲连接(1次/min 10min 3 = 30)
redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream. at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:199) at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40) at redis.clients.jedis.Protocol.process(Protocol.java:151) at redis.clients.jedis.Protocol.read(Protocol.java:215) at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340) at redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:259) at redis.clients.jedis.Connection.getBulkReply(Connection.java:248) at redis.clients.jedis.Jedis.get(Jedis.java:153)
2s 连接空闲,redis 回了一个fin包,来关闭这个连接
那我们再拿来用,就抛了JedisConnectionException: Unexpected end of stream的异常
当然你会说,我们实际使用的例子,用完一次就会换回去池子里,不会拿了连接,发一次命令,过一会再发
其实这个不是个什么问题,本质上是一样的,不信我们来试一下,这次我们把连接池大小设置的小一点,比如1
fun main(args: Array<String>){ val context = ClassPathXmlApplicationContext("classpath:*.xml") context.start() val redisTemplate: RedisTemplate<Serializable, Serializable> = context.getBean(RedisTemplate::class.java) asRedisTemplate<Serializable, Serializable> redisTemplate.opsForValue().get("hallo") Thread.sleep(3000) redisTemplate.opsForValue().get("hallo") System.`in`.read() }
嗯,出现了跟线上一模一样的堆栈
Exception in thread "main" 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:67) at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:41) 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:242) at org.springframework.data.redis.connection.jedis.JedisConnection.get(JedisConnection.java:1220) at org.springframework.data.redis.core.DefaultValueOperations$1.inRedis(DefaultValueOperations.java:46) at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:57) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:207) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:169) at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:91) at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:43) at JedisTest5Kt.main(JedisTest5.kt:24) Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream. at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:199) at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40) at redis.clients.jedis.Protocol.process(Protocol.java:151) at redis.clients.jedis.Protocol.read(Protocol.java:215) at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340) at redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:259) at redis.clients.jedis.BinaryJedis.get(BinaryJedis.java:244) at org.springframework.data.redis.connection.jedis.JedisConnection.get(JedisConnection.java:1218) ... 7 more