遇到过这样一个严重问题: 发布的项目不知从什么时候开始,每月会出现一两次串号问题。串号现象指的是,用户用账号A登录系统,然后某个时间,登录账号自动变成了B。 串号出现的时间不定,测试平台难以重现,且后台检测不到错误,难以定位。当时各种排查,最后发现问题果然是出在缓存redis上,JedisPool使用有问题。
JedisPool使用注意事项:1、每次从pool获取资源后,一定要try-finally释放,否则会出现很多莫名其妙的错误。 2、资源释放不能一致使用returnBrokenResource【项目问题就出在第二条注意事项上】。 相关代码代码修改前大致如下: public void closeResource(Jedis jedis) {
if (null != jedis) {
jedisPool.returnResource(jedis);
}
}
代码修改后大致如下【isOK正常设为true,捕获到异常如JedisConnectionException时传入false】: public void closeResource(Jedis jedis, boolean isOK) {
if (null != jedis) {
if(!isOK){
LOG.error("do some things..");
jedisPool.returnBrokenResource(jedis);
}else{
jedisPool.returnResource(jedis);
}
}
}
相关源码: 分析源代码,可以知道本来应该执行returnBrokenResourceObject方法,结果却执行了returnResourceObject,并且执行returnResourceObject过程中没有报错。
具体原因应该就在方法体里面,可惜点进去并没有分析出具体是哪几行代码导致了串号的出现 = =! 不过当时项目return方面进行了修改后,错误确实没有再出现。 下面这篇文章也讲解了returnSource的相关注意事项,大家可以参考下 http://www./jedis-returnresource使用注意事项/ PS:当时项目使用的是Jedis2.7.0,不用通过图片1可以发现Jedis3.0后,returnResource就不使用了,建议用close替换。 即:jedisPool.returnResource(jedis) ---> jedis.close();
|