"ClassCastException: java.lang.Long cannot be cast to [B", Jedis “Socket读取超时”导致“返回值类型错误”

从异常信息来看,首先是在'zadd'操作时出现"Socket读取超时异常",具体异常信息"JedisConnectionException: java.net.SocketTimeoutException: Read timed out"。

出现异常后,会销毁这个阻塞的Jedis连接池对象(CustomShardedJedisPool.returnBrokenResource(CustomShardedJedisPool.java:121)),但在请求Redis服务端关闭连接时,出现"强制类型转换异常",具体异常信息"ClassCastException: java.lang.Long cannot be cast to [B"。

网上的大神说:

查看 Jedis 源码发现它的Connection中对网络输出流做了一个封装(RedisInputStream),其中自建了一个buffer。当发生异常的时候,这个buffer里还残存着上次没有发送或者发送不完整的命令。这个时候没有做处理,直接将该连接返回到连接池,那么重用该连接执行下次命令的时候,就会将上次没有发送的命令一起发送过去,所以才会出现上面的错误“返回值类型不对”。、

解决的办法:

jedispool资源释放

    public void close() {
    if (dataSource != null) {
      if ( client.isBroken()) {
        this.dataSource.returnBrokenResource(this);
      } else {
        this.dataSource.returnResource(this); 
      }
    } else {
      client.close(); //2.9 以后的版本
    }
  }

所以对使用到jedis的地方进行一场捕获 进行资源的释放

    try{
            if (userName != null && jedis.exists(userName) && jedis.get(userName).equals(token)) {
                return true;
            }
        }catch (Exception e){
            jedis.close();
        }

添加synchronized关键字

jedis不支持多线程的原因,在你调用del等方法时,在调用方法申明前加上关键字 synchronized就可以解决问题。比如delkey调用del方法,在delkey方法前加synchronized就可以了

你可能感兴趣的:("ClassCastException: java.lang.Long cannot be cast to [B", Jedis “Socket读取超时”导致“返回值类型错误”)