jedis连接池爆满导致的服务不可用

Posted 奇谋只在绝境中诞生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jedis连接池爆满导致的服务不可用相关的知识,希望对你有一定的参考价值。

生产环境was线程数300,jedis连接池连接数100.

在业务高峰期,查看日志发现大量could not get a resource from a pool的异常,抓取javacore文件发现was线程大量进入parked状态,查看jedis源码发现连接池底层使用common-pool实现,而common-pool其中有这样一段代码:

if (p == null) {
if (borrowMaxWaitMillis < 0) {
p = idleObjects.takeFirst();
} else {
p = idleObjects.pollFirst(borrowMaxWaitMillis,
TimeUnit.MILLISECONDS);
}
}
新来的线程会从jedis自己实现的LinkedBlockingQueue中拿链接,如果连接池没有空闲链接并且已键连接数已达上限,那么
public E pollFirst(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
lock.lockInterruptibly();
try {
E x;
while ( (x = unlinkFirst()) == null) {
if (nanos <= 0) {
return null;
}
nanos = notEmpty.awaitNanos(nanos);
}
return x;
} finally {
lock.unlock();
}
}
当前线程也就是was线程就会parked等待notEmpty信号,导致大量请求进不来堵死,首先我们考虑参数配置不合理,业务高峰期热点数据在redis中,大量的redis访问,我们改成300was链接,200redis链接,情况明显好转,但是在高峰期仍有部分请求时间超长,was线程parked的现象出现,更改jedis连接池参数,把maxWaitMillis参数调小,从最初的2000毫秒调到500,在业务高峰期,服务器资源紧张,新来的请求如果获取不到资源,立即报错返回,保证现有业务的正常运行算是一种权衡的办法。

以上是关于jedis连接池爆满导致的服务不可用的主要内容,如果未能解决你的问题,请参考以下文章

线程太多导致socket连接池爆满,进程启动不了

DBCP连接池使用问题

Jedis连接池(实际项目可用)

springboot 服务卡死 连接池查询无响应问题解决

将连接池与 Jedis 一起使用

HttpClient连接池耗尽引发雪崩问题