当前位置:Java -> 揭开秘密:仅使用 2.5G RAM 在 JMeter 中实现 50K 并发用户负载

揭开秘密:仅使用 2.5G RAM 在 JMeter 中实现 50K 并发用户负载

Apache JMeter是一个开源的基于Java的工具,用于对各种服务进行负载和性能测试,特别是用于Web应用程序。它支持多种协议,如HTTP、HTTPS、FTP等。JMeter可以模拟对服务器的大量负载,以分析在不同条件下的性能。它提供了GUI和非GUI模式,用于测试配置,并且可以以各种格式显示测试结果。JMeter还支持分布式测试,使其能够同时处理多个测试线程。通过插件可以扩展其功能,使其成为性能测试中一个多功能和广泛使用的工具。

JMeter因其出色的并发模型而脱颖而出,该模型决定了它如何并行执行请求。JMeter的并发模型依赖于线程池,在Java和其他几种编程语言中被广泛认可作为并行处理的标准方法。然而,就像任何优势一样,也存在一个显着的权衡:JMeter并发模型的资源密集型特性。

在JMeter中,每个线程对应一个Java线程,进一步利用操作系统(OS)线程进行执行。操作系统线程虽然在完成并发任务方面很有效,但在内存消耗和上下文切换时的CPU使用率方面具有一定的权重,这一特性给JMeter的性能提出了显著挑战。此外,某些操作系统对可以生成的线程总数施加严格限制,也对JMeter的能力施加了隐含的限制。

释放真正的力量,Java 21来拯救

在过去几年中,项目织在Java社区中引起了广泛关注,并在JEP-444的几次早期预览发布后,最终被纳入到Java 21中。

Java threads

Java的虚拟线程,也称为轻量级或用户模式线程,在项目织的实验性功能下被引入,此功能现在已正式纳入到Java 21中。

虽然该功能的细节很有趣,但它并不是我们今天讨论的重点,因此我们不会在这一刻深入研究它们。

JMeter

代码审查显示了一个简单的流程,通过复制ThreadGroup类来创建一个新线程组。在这个实例中,我们只是从我们想要修改的ThreadGroupJMeter类中复制了逻辑。

一个需要注意的关键方法是startNewThread,它负责创建线程。我们在这个方法中做了一行修改:

原始代码行:

Thread newThread = new Thread(jmThread, jmThread.getThreadName());


已被替换为以下内容:

Thread newThread = Thread.ofVirtual()
.name(jmThread.getThreadName())
 .unstarted(jmThread);


在这个修改中,我们不是创建一个传统线程,而是创建一个在Java项目织中引入的虚拟线程,这种变化允许更轻量级、更高效的线程处理。

此外,还有其他修改,比如在addNewThread方法中移除synchronized块,并在其他几个地方更新类似的线程创建逻辑。

设置

  1. 我快速设置了nginx,它总是返回200 ok响应:
# nginx.conf 
location /test {
    return 200 'OK';
 }


2. 添加虚拟线程组元素:

Virtual Thread Group

3. 配置线程:您将在右线程组中看到标题为虚拟线程属性的标题。

Configure Threads

4. 准备,开始……!!最终结果:

最终结果

我的主要关注点并不是服务器的响应速度或其扩展到5万用户的能力(通过一些调整,这可能很容易实现)。相反,我更感兴趣的是观察 JMeter 如何生成和处理负载,无论服务器响应成功与否。

总结

JMeter 传统上由于涉及网络请求的 I/O 绑定性质而资源密集。但是,引入虚拟线程后,其性能显著改善。利用虚拟线程使 JMeter 能够在处理重负载时运行平稳高效,没有任何故障。

源代码

有兴趣尝试的任何人,可以查看以下GitHub 项目获取更多详情。

推荐阅读: 16.如何对索引进行优化?

本文链接: 揭开秘密:仅使用 2.5G RAM 在 JMeter 中实现 50K 并发用户负载