我正在运行一个JMeter脚本,400 TPS和48小时,它是REST API脚本。
JMeter版本:5.6.2
JMeter脚本配置如下:
Threads : 500
Ramp Up : 100
Duration: 48 hours
TPS : 400 Using Throughput Shaping Timer
在测试过程中,我逐渐观察到运行JMeter的负载生成器VM上的CPU和内存利用率不断增加。36-40小时后无React
CPU Utilisation >90% and Memory Utilisation >80%
其中运行JMeter脚本的负载生成器具有8个CPU和16 GB RAM,我已经使用-Xmx 1g和-Xmx 10 g堆配置了JMeter。
我已经采取了线程和堆转储与以下分析:
使用TOP命令确认高CPU和内存利用率的过程详细信息
top - 11:38:00 up 54 days, 12:01, 1 user, load average: 8.83, 7.98, 8.01
Threads: 541 total, 8 running, 533 sleeping, 0 stopped, 0 zombie
%Cpu(s): 97.9 us, 1.4 sy, 0.0 ni, 0.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16247380 total, 2010332 free, 13876416 used, 360632 buff/cache
KiB Swap: 4190204 total, 3953660 free, 236544 used. 2001252 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
107296 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:12.27 GC Thread#1
107297 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:08.55 GC Thread#2
107298 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:09.84 GC Thread#3
107299 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:08.98 GC Thread#4
107300 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:12.21 GC Thread#5
107301 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:11.67 GC Thread#6
107302 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:10.00 GC Thread#7
107273 sam_user 20 0 17.1g 12.3g 20572 R 94.1 79.2 293:08.49 GC Thread#0
获取堆转储后的堆分析:
问题嫌疑人1:
One instance of org.apache.logging.slf4j.Log4jLoggerFactory loaded by
org.apache.jmeter.DynamicClassLoader @ 0x580103ba0 occupies 83,61,68,864 (17.61%) bytes.
The memory is accumulated in one instance of
java.util.concurrent.ConcurrentHashMap$Node[], loaded by <system class loader>, which
occupies 83,61,68,384 (17.61%) bytes.
Keywords
org.apache.logging.slf4j.Log4jLoggerFactory
org.apache.jmeter.DynamicClassLoader @ 0x580103ba0
java.util.concurrent.ConcurrentHashMap$Node[]
问题嫌疑人2:
1,20,38,109 instances of java.lang.String, loaded by <system class loader> occupy
1,82,80,04,808 (38.50%) bytes.
These instances are referenced from one instance of
java.util.concurrent.ConcurrentHashMap$Node[], loaded by <system class loader>, which
occupies 83,61,68,384 (17.61%) bytes.
Keywords
java.lang.String
java.util.concurrent.ConcurrentHashMap$Node[]
问题嫌疑人3:
1,20,16,586 instances of org.apache.logging.log4j.core.Logger, loaded by
org.apache.jmeter.DynamicClassLoader @ 0x580103ba0 occupy 1,53,81,23,008 (32.39%) bytes.
These instances are referenced from one instance of
java.util.concurrent.ConcurrentHashMap$Node[], loaded by <system class loader>, which
occupies 45,16,41,568 (9.51%) bytes.
Keywords
org.apache.logging.log4j.core.Logger
org.apache.jmeter.DynamicClassLoader @ 0x580103ba0
java.util.concurrent.ConcurrentHashMap$Node[]
我假设这是Apache JMeter的问题,你能提供一个解决方案吗?
2条答案
按热度按时间5f0d552i1#
您的“分析”只显示堆使用率太高,garbage collection占用了大量资源。
如果您只有一个HTTP请求采样器,并且观察到内存利用率随着时间的推移而变高,这确实是JMeter中的一个问题,您应该report it via JMeter Github
然而,也可能是你的脚本导致了这种行为,即。你正在创建新的JMeter Variables,并且永远不会删除它们。或者你使用相同的虚拟用户48小时,我不认为这是一个有效的用例。或者你正在使用配置不好的Groovy scripts,它在每次调用时都会生成新的类。或者你正在使用Listeners,它不添加任何值,只积累数据。
因此,如果您遵循JMeter Best Practices并且没有任何外部组件/代码的情况下可以重现问题-这是JMeter问题。否则就是你的测试设计问题了。
0md85ypi2#
您的JMeter示例中似乎确实存在内存泄漏。然而,没有足够的证据来证明这是由JMeter bug引起的“假设”或结论。
我能看到的唯一线索是,泄漏的对象似乎是大量的
Logger
示例和ConcurrentHashMap
中(几乎)匹配数量的字符串。根据Logger
类名,看起来您使用的是log4j 2,而log4j 2使用ConcurrentHashMap
来实现日志记录器注册表。因此,一个可能的解释是 something 正在创建过多的不同Logger
示例;即具有不同的名称。我对JMeter问题跟踪器进行了快速搜索,以查找提到“内存泄漏”的问题。没有一个与您的症状明显匹配,但我可能错过了一些东西,而且您给我们的关于JMeter脚本的信息很少。(您可以自行查看这些问题here。)
你能提供一个解决方案吗?
根据您提供的信息,我们无法这样做。
如果我有这个问题,我会使用堆转储分析器来查看
ConcurrentHashMap
中的条目。假设它是logger注册表Map,那么在键中应该有一个很大的线索。