Apache Jmeter3.0压测数据库OOM的Bug排查

简介:

一、引言

Apache Jmeter 2.13(以下简称Jmeter2)版本后,2.X系列就作古了。前些日子,Apache Jmeter 3.0(以下简称Jmeter3)版本正式发布,新生的事物,功能肯定强大了很多,但作为开源产品,稳定性自然要打些折扣,一位同学前几天在使用Jmeter3时不幸中招。

二、问题描述

原本好用的JDBC请求脚本,压测数据库,使用Jmeter3版本时直接OOM,回退至Jmeter2,一切正常,啥也别说,肯定是又出Bug了,本着求实的精神,咱来看看Jmeter3为毛OOM了。

三、排查过程

1.找出OOM的对象

首先在Jmeter3中配置输出HeapDump文件,在jmeter.sh中增加以下一行:
JVM_ARGS="-Xms512m -Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=~/gc.hprof
然后启动Jmeter程序,观察Jmeter的JVM内存变化,再次OOM了,把输出的gc.hprof文件,利用Memory Analyzer来分析,得到一堆index文件如下图:

利用Eclipse的MAT插件,加载全部的index文件,查看哪个对象占用了内存,如下图:

看到AbstractJDBCTestElement类中的perConnCache对象,占用了441M的内存,确定是这个对象内存泄露了。

2.找出导致OOM的原因

先来看看这个perConnCache究竟是做什么用的

/**
* Cache of PreparedStatements stored in a per-connection basis. Each entry of this
* cache is another Map mapping the statement string to the actual PreparedStatement.
* At one time a Connection is only held by one thread
*/

private static final Map<Connection, Map<String, PreparedStatement>> perConnCache =
new ConcurrentHashMap<Connection, Map<String, PreparedStatement>>();

这是一个HashMap,用来缓存每个连接(即Connection,下文简称为Conn)的PreparedStatements。而笔者的压测脚本中,最大Conn数设定的是10个,就是说,perConnCache的size最大应该是10才对,OK,估计问题就出在这里,笔者猜测应该是每次请求的Conn都具有不同的HashCode。
为了验证这个猜测,笔者用远程Debug来查看一下,每次获取Conn时的HashCode。
Debug后发现,在Jmeter3中有一个有趣的现象,每次获取到的Conn果然具有不同的HashCode,但是Jmeter3与DB的Conn总数却刚好是10个,就是说——物理连接的总数量并没有变,但每次从连接池获取到的Connection对象却一直在变。
笔者又Debug了一下Jmeter2,Jmeter2的结果是符合预期的,物理连接的总数是10个,perConnCache的size也是10,每次从连接池中获取的Conn也都能在perConnCache中命中。

3.锁定问题点

不论是Jmeter2还是Jmeter3,JDBCSampler的实现都是一样的:

如图所示,这里有3个关键操作,获取Conn,执行SQL,关闭Conn。在执行SQL的步骤中,perConnCache会进行缓存验证,如果没有命中,则把新的Conn缓存。
每次getConnection()都是连接池的操作,所以,问题就应该出在Jmeter3使用的连接池实现上。

4.OOM原因解析

下面来解释一下,为什么Jmeter3的连接池就会出现OOM的问题。
因为Jmeter3使用的是dbcp2,在getConnection()方法中,每次不是直接返回Connection对象,而是都会新new一个PoolGuardConnectionWrapper对象,看下面的代码:

可以看到,Conn并没有变,但是每次取到的对象都是重新new的包裹类PoolGuardConnectionWrapper,每次都是新的对象,HashCode当然就不一样了,在HashMap无法命中,所以最终每一次getgetConnection()时,perConnCache都产生一个新成员,最终OOM。
为啥Jmeter2没有这个问题呢?Jmeter2使用的是excalibur-datasource,每次Connection取到的就是com.mysql.jdbc.JDBC4Connection对象本身,自然在perConnCache里面就可以命中了

四、修改方式:

方式一:抛弃dbcp2,回退到excalibur-datasource,问题解决
方式二:修改perConnCache缓存机制,不是用Connection作为Key,而是利用sql的内容作为key,当然也可以直接删除这个Cache。
笔者尝试去掉了缓存机制,没有再发生OOM问题,压测结果对整体的TPS影响也不大

五、结论:

Jmeter3稳定性还有待考验,近期不推荐使用,建议使用Jmeter2.13来替代。

相关文章
|
11月前
|
Rust Java 测试技术
还在用 Jmeter 做压测?试试 oha 吧!你会毫不犹豫的爱上它!
在 Web 服务与 API 性能测试中,选择合适的工具至关重要。本文介绍基于 Rust 的高效性能测试工具 **OHA**,并与经典工具 **JMeter** 对比。OHA 以其高性能、低资源占用和简洁易用的特点脱颖而出,适合高并发场景下的快速测试。而 JMeter 功能丰富、支持多协议,适合复杂测试需求。两者各有优势,选择需根据具体场景决定。OHA 安装简单,命令行操作便捷,是性能测试的新利器。
553 0
还在用 Jmeter 做压测?试试 oha 吧!你会毫不犹豫的爱上它!
|
12月前
|
安全 Apache 数据库
【倒计时3天】NineData x Apache Doris x 阿里云联合举办数据库技术Meetup,5月24日深圳见!
5月24日,NineData联合Apache Doris与阿里云在深圳举办数据库技术Meetup。活动聚焦「数据实时分析」与「数据同步迁移」两大领域,邀请行业专家分享技术趋势、产品实践及解决方案,助力企业构建高效安全的数据管理体系。时间:14:00-17:30;地点:深圳新一代产业园2栋20楼会议室。线下名额有限(80人),速报名参与深度交流!
334 1
|
SQL 关系型数据库 MySQL
遇到mysql数据库死锁,你会怎么排查?
遇到mysql数据库死锁,你会怎么排查?
1285 0
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
501 25
|
存储 监控 数据处理
flink 向doris 数据库写入数据时出现背压如何排查?
本文介绍了如何确定和解决Flink任务向Doris数据库写入数据时遇到的背压问题。首先通过Flink Web UI和性能指标监控识别背压,然后从Doris数据库性能、网络连接稳定性、Flink任务数据处理逻辑及资源配置等方面排查原因,并通过分析相关日志进一步定位问题。
1194 61
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
缓存 Java 测试技术
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
使用JMeter对项目各个接口进行压力测试,并对前端进行动静分离优化,优化三级分类查询接口的性能
914 10
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
|
存储 消息中间件 人工智能
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
早期 MiniMax 基于 Grafana Loki 构建了日志系统,在资源消耗、写入性能及系统稳定性上都面临巨大的挑战。为此 MiniMax 开始寻找全新的日志系统方案,并基于阿里云数据库 SelectDB 版内核 Apache Doris 升级了日志系统,新系统已接入 MiniMax 内部所有业务线日志数据,数据规模为 PB 级, 整体可用性达到 99.9% 以上,10 亿级日志数据的检索速度可实现秒级响应。
1119 14
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
|
SQL 监控 测试技术
一次压测引发的数据库CPU飙升...
一次压测过程中,当数据库的qps和tps都正常时,如果cpu利用率异常的高,应该如何排查?希望通过这篇文章,给你一些启发。
|
SQL 存储 Java
数据库———事务及bug的解决
事务的一些概念,并发事务以及并发事务引起的bug,脏读,不可重复读,幻读,数据库中的隔离级别,事务的简单应用

推荐镜像

更多