Redis 使用过程当中出现了大量的读取超时异常,如下:
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:202)
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)
查了好久,最终发现了RedisService代码如下:
public Pipeline pipelined() {
Jedis jedis = getJedis();
try {
return jedis.pipelined();
} finally {Streams.safeClose(jedis);}
}
一旦调用Pipeline,jedis被归还到池里了。而此时外部操作pipeline其实操作的是已经被归还到池里的jedis,如果这个jedis对象被其他线程取出调用,就出现了线程安全问题,数据流不能被正确的解析,导致各种读取超时或者反序列化失败异常。