java----记录jedispool的一个坑 jedispool导致线程阻塞

背景

一个多线程的消费任务,从kafka读数据放到LinkedBlockingQueue,另一个线程消费此链表数据。
在消费的时候本意期望用redis实现一个锁。
java中有对应的包jedisLock。
从Jedispool中获取一个连接去进行redis操作。

代码

		Jedis jedis = jedisPool.getResource();
        JedisLock lock = new JedisLock(jedis, key, 10000, 30000);
        try {
            lock.acquire();
			//
        } catch (Exception e) {
            logger.error("redis connect failed");
            logger.error(e.getMessage());
            }
        } finally {
            lock.release();
        }

现象

在测试环境没有问题。
在线上消费一段时间就停止消费。程序处于假死状态。
而且有些时候很长时间不会假死,有些时候一会就会假死。
于是开始排查。

日志

开始消费正常。之后线程开始sleep。程序卡死状态。在这里插入图片描述

jedis源码分析

为了追踪这个数目,设置了一个变量sum,消费一条数据sum++,发现每次都是消费1024个就开始阻塞。
继续跟踪,发现在jedispool获取资源的时候阻塞,也即获取不到资源,阻塞住在获取资源处。
在这里插入图片描述
redis配置为最大连接数1024个。
开始思考,为什么获取不到资源不会抛异常,会阻塞,进而去看Jedis源码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
maxWaitMillis默认为-1。
继续追进代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这里,线程就锁住了,获取不到资源。
这时候,我又有一个问题,为什么之前的redis资源不会自己释放呢,之前用线程池的时候,会自己回收,为什么jedisPool没有。必须要手动jedis.close,我去看jedis.close的代码。
在这里插入图片描述

结论

1.在使用jedispool的时候一定要注意资源的释放。
2.一定要注意maxWaitMillis的设置。
否则会出现阻塞的问题。一定注意!!!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章