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

本文涉及的产品
性能测试 PTS,5000VUM额度
简介:

一、引言

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来替代。

相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
相关文章
|
15天前
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
5月前
|
存储 SQL BI
毫秒级查询性能优化实践!基于阿里云数据库 SelectDB 版内核:Apache Doris 在极越汽车数字化运营和营销方向的解决方案
毫秒级查询性能优化实践!基于阿里云数据库 SelectDB 版内核:Apache Doris 在极越汽车数字化运营和营销方向的解决方案
毫秒级查询性能优化实践!基于阿里云数据库 SelectDB 版内核:Apache Doris 在极越汽车数字化运营和营销方向的解决方案
|
2月前
|
缓存 Java 测试技术
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
使用JMeter对项目各个接口进行压力测试,并对前端进行动静分离优化,优化三级分类查询接口的性能
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
|
5月前
|
Apache 数据库
杨校老师课堂之基于Apache的数据库连接池DBCP的工具类开发
杨校老师课堂之基于Apache的数据库连接池DBCP的工具类开发
27 0
|
3月前
|
存储 消息中间件 人工智能
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
早期 MiniMax 基于 Grafana Loki 构建了日志系统,在资源消耗、写入性能及系统稳定性上都面临巨大的挑战。为此 MiniMax 开始寻找全新的日志系统方案,并基于阿里云数据库 SelectDB 版内核 Apache Doris 升级了日志系统,新系统已接入 MiniMax 内部所有业务线日志数据,数据规模为 PB 级, 整体可用性达到 99.9% 以上,10 亿级日志数据的检索速度可实现秒级响应。
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
|
2月前
|
关系型数据库 MySQL 测试技术
《性能测试》读书笔记_数据库优化
《性能测试》读书笔记_数据库优化
31 7
|
3月前
|
存储 监控 数据可视化
性能监控之JMeter分布式压测轻量日志解决方案
【8月更文挑战第11天】性能监控之JMeter分布式压测轻量日志解决方案
94 0
性能监控之JMeter分布式压测轻量日志解决方案
|
3月前
|
消息中间件 人工智能 Kafka
Apache Kafka + 向量数据库 + LLM = 实时 GenAI
生成式AI(GenAI)革新了企业架构,催生新数据集成模式与最佳实践。借助Apache Kafka与Apache Flink,企业能高效处理大规模实时数据,连接各类数据库与分析平台。Kafka作为核心组件,支持GenAI应用如服务台自动化、聊天机器人及内容审核。结合大型语言模型(LLM)、检索增强生成(RAG)与向量数据库,Kafka与Flink共同打造强大数据流处理能力,克服GenAI挑战,如昂贵训练成本、数据时效性与准确性。通过语义搜索与RAG设计模式,确保LLM生成内容可靠无误。
76 0
|
4月前
|
测试技术 Linux
linux 服务器运行jmeter 进行服务性能压测
linux 服务器运行jmeter 进行服务性能压测
399 0
|
5月前
|
SQL 存储 运维
网易游戏如何基于阿里云瑶池数据库 SelectDB 内核 Apache Doris 构建全新湖仓一体架构
随着网易游戏品类及产品的快速发展,游戏数据分析场景面临着越来越多的挑战,为了保证系统性能和 SLA,要求引入新的组件来解决特定业务场景问题。为此,网易游戏引入 Apache Doris 构建了全新的湖仓一体架构。经过不断地扩张,目前已发展至十余集群、为内部上百个项目提供了稳定可靠的数据服务、日均查询量数百万次,整体查询性能得到 10-20 倍提升。
网易游戏如何基于阿里云瑶池数据库 SelectDB 内核 Apache Doris 构建全新湖仓一体架构

推荐镜像

更多