前言
因博主近日需要替换掉自建的codis,改为连接阿里云Redis,所以要对手上的项目进行改造,涉及改动的模块大约有20个以上(老项目)。
问题
在改造过程中,创建 JedisPool 时遇到了以下异常:
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
这个异常看起来很简单清晰,但恰恰正是 JedisConnectionException 这个错误误导了我,因为这根本不是 Jedis 连接的问题,而是代码中使用了 JSONObject.toJSONString(jedisPool) 这句代码引发的异常。如下图所示:
问题代码
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(1000);
poolConfig.setMaxIdle(100);
poolConfig.setMaxWaitMillis(100 * 1000);
poolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool(poolConfig, host, 6379, 10000, password);
logger.info("Jedis连接池初始化成功");
Jedis resource = jedisPool.getResource();
System.out.println("连接是否成功:" + resource.isConnected());
String key = "a_zebe_test_key";
resource.set(key, UUID.randomUUID().toString());
System.out.println("获取设置的KEY:" + resource.get(key));
// 这行代码会产生 JedisConnectionException 异常
logger.info("初始化Jedis连接池(阿里云Redis)成功:{}", JSONObject.toJSONString(jedisPool));
经验总结
一看到 JedisConnectionException,首先想到肯定是连接Redis的问题,没想到居然是 JSONObject.toJSONString 引发的问题。这次吸取了教训,看来 fastjson 被人诟病是有原因的,之前多个版本被曝出重大漏洞,这次的问题 fastjson 也给我留下了很不好的印象,决定以后谨慎用 fastjson,尤其是 toJSONString 方法。
另外,看到问题报错时,要仔细分析异常堆栈,不能被抛出的异常类名称所迷惑,要找到真正的异常原因,博主这次就是被 JedisConnectionException 这个异常类名称迷惑,而没有仔细查看异常堆栈,排查了很久才找到问题。
把本文分享出来,防止后人踩同样的坑。