分享

jedis 高并发异常阻塞解决 returnResource 和 returnBrokenResource

 昵称597197 2018-03-23

遇到过这样一个严重问题:
发布的项目不知从什么时候开始,每月会出现一两次串号问题。串号现象指的是,用户用账号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);  
        }   
    }  
}  

相关源码:

图片1
分析源代码,可以知道本来应该执行returnBrokenResourceObject方法,结果却执行了returnResourceObject,并且执行returnResourceObject过程中没有报错。

具体原因应该就在方法体里面,可惜点进去并没有分析出具体是哪几行代码导致了串号的出现 = =!
不过当时项目return方面进行了修改后,错误确实没有再出现。

下面这篇文章也讲解了returnSource的相关注意事项,大家可以参考下
http://www./jedis-returnresource使用注意事项/

PS:当时项目使用的是Jedis2.7.0,不用通过图片1可以发现Jedis3.0后,returnResource就不使用了,建议用close替换。
即:jedisPool.returnResource(jedis) ---> jedis.close();

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约