行业资讯 2025年08月6日
0 收藏 0 点赞 517 浏览 1921 个字
摘要 :

文章目录 现象 查看不断增长的线程 验证推断 找出真凶, 哪里创建这么多连接池 修复 本文主要讲解关于如何排查解决大量创建连接池导致的线程泄漏问题相关内容,让我们来……




本文主要讲解关于如何排查解决大量创建连接池导致的线程泄漏问题相关内容,让我们来一起学习下吧!

对的, 你没看错, 大量创建连接池, 连接是稳定的, 但是却导致线程暴涨.

现象

这是一个Java 应用, 有监控它的线程总数, 各个服务器的线程总数看上去是这个样子的:排查解决大量创建连接池导致的线程泄漏问题

查看不断增长的线程

通过thread dump, 我们可以看到里面包含居多以 Connection evictor命名的线程, 如下:排查解决大量创建连接池导致的线程泄漏问题

还碰巧看到一个正在做事的线程栈, 从这里我们可以大概猜出这是 Apache httpClient 的连接池, 它正在清理长期不用的连接.

我们推测这个应用在不断的创建连接池, 然后就抛弃不用, 然后就该 Connection evictor 出场来清理这些不再被使用的连接.

验证推断

既然推断创建了很多连接池, 那么我们就来看看到底有多少连接池.

$ jcmd 2447856 GC.class_histogram | grep PoolingHttpClientConnectionManager
 223:           3211          101568  org.apache.http.impl.conn.PoolingHttpClientConnectionManager
 224:           3211          101568  org.apache.http.impl.conn.PoolingHttpClientConnectionManager$ConfigData
 284:           3211          86176  org.apache.http.impl.conn.PoolingHttpClientConnectionManager$InternalConnectionFactory

上面第二列的输出表示有多少这样的对象, 不出所料, 果然有这么多连接池.

找出真凶, 哪里创建这么多连接池

既然创建这么多 PoolingHttpClientConnectionManager 对象, 那么就看看到底哪里新建的这些对象吧. 使用 Btrace 工具, 使用如下Btrace 脚本:

import org.openjdk.btrace.core.annotations.*;
import static org.openjdk.btrace.core.BTraceUtils.*;
 
import org.openjdk.btrace.core.BTraceUtils.Strings;
 
@BTrace
public class ConnectionPoolTracer {
 
    @OnMethod( clazz=\"/org\\.apache\\.http\\.impl\\.conn\\.PoolingHttpClientConnectionManager/\", method=\"<init>\" )
    public static void createPool() {
        println(Strings.strcat(\"current thread: \", name(currentThread())));
        println(jstackStr());
    }
}

去执行, 得到如下栈:

org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:165)
org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:988)
org.tianxiaohui.utils.HttpConnectionUtils.getHttpConnection(HttpConnectionUtils.java:56)
org.tianxiaohui.utils.HttpUtils.createClientWithSSL(HttpUtils.java:144)
org.tianxiaohui.utils.HttpUtils.createClientWithSSL(HttpUtils.java:128)
org.tianxiaohui.service.CustomProperties.getVariable(CustomProperties.java:1133)

原来是每次调用 HttpConnectionUtils.getHttpConnection() 这个方法, 就会创建一个新的连接池.

修复

全局共享的一个连接池.

以上就是关于如何排查解决大量创建连接池导致的线程泄漏问题相关的全部内容,希望对你有帮助。欢迎持续关注潘子夜个人博客(www.panziye.com),学习愉快哦!

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/10071.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号