JMeter调优

背景

可能多少对于JMeter存在这样一些刻板印象:

  • JMeter 消耗大量内存…
  • JMeter 产生 OutOfMemory 错误…
  • JMeter 消耗大量 CPU…
  • 其他

那么,是否还有调优的余地?可能指望它像一些轻量级工具那样轻巧是有点难了,比如ab,比如wrk。但是如果能够将jmeter优化成只比这些工具多消耗一些不多的资源,那么多个jmeter协同工作的威力就可以充分发挥出来了。

调优清单

下面是一些调优技巧清单,还有很多其他更细致的优化手段没有列出来:

  1. 从命令行运行 :避免在负载测试期间使用 JMeter UI,它会占用大量内存
  2. 避免使用监听器 :避免使用图形或结果表等 UI 监听组件
  3. 增加 JVM 堆空间 :以更大的内存量启动 JMeter,如下例所示:JVM_ARGS="-Xms512m -Xmx512m" jmeter.sh1,考虑将每个 JVM 的内存增加到 8GB,在同一台机器上至少有 8GB 的​​可用 RAM。
  4. 使用最新的 JMeter 版本 :JMeter 会定期随着新版本的发布而改进。 坚持使用最新版本以获得最新的改进。
  5. 使用 Regexp 变量提取器从响应中提取数据 :但永远不要使用 的 Body(未转义) 解析整个响应 DOM 树 选项。 避免使用 Json、Xpath 和任何其他花哨的后处理器。 这些会消耗大量内存。
  6. 避免从大型响应中提取数据 :整个响应都保存在内存中,从而显着增加了内存消耗。 只提取必要的数据,而不是更多。
  7. 每台机器模拟合理数量的线程 每台机器 :避免 模拟超过 1000 个用户。 通常,瓶颈是网络连接(在最佳云实例上为 1Gbps)。 JVM 不能很好地处理超过 2000 个线程。
  8. 在普通机器上分配负载 :避免使用少数具有特殊硬件(例如 16 核 / 128GB RAM)的机器,坚持使用普通机器(4 核,16GB RAM)并使用更多机器代替。 JMeter 无法利用这么多 RAM,因为 JVM 不能很好地处理大于 16GB 的 Xmx。
  9. 明智地使用断言 :断言会增加内存使用量。 使用几个是合理的,但避免使用太多,因为它会显着增加内存使用量。 此外,避免对大型服务器响应(大于 1MB)进行断言。
  10. 运行后生成报告 后, :负载测试完成 使用输出的 JTL 文件创建报告。 构建报告需要大量的 CPU 和内存资源。
  11. 在大多数情况下,网络是瓶颈 :这意味着最好拥有具有良好网络连接的中型机器,而不是具有低网络能力的强大机器。
  12. 避免 BeanShell 脚本 :这些脚本比嵌入在 JSR223 采样器中的 Groovy 脚本使用更多的 CPU 来执行。 如果你需要运行自定义逻辑,请坚持使用 JSR223 采样器。
  13. 不要在分布式模式下运行 :分布式模式适用于 20-30 台机器,如果运气好的话,最多可以使用 40-50 台机器。 这会将你限制为 20-50k 并发用户。 相反,通过在开始测试之前发送 JMX 并在完成后检索 JTL 文件来独立运行每个 JMeter 实例。 JMeter 用于在负载生成器和控制器之间进行通信的 RMI 协议效率不高。
  14. 在 JTL 中仅存储指标而不是请求/响应 在 JTL 中 :避免 存储请求、响应、响应头,因为它会使用大量资源。 当然,在发生故障时让服务器响应很好,但是在运行大负载测试时就不合理了。
  15. 作为最后的手段,调整 JVM :垃圾收集器 (-XX:+UseConcMarkSweepGC)、服务器 JVM (-server) 等设置可以通过编辑 JMeter 启动程序脚本在 JVM_ARGS 中设置。 但是,一旦你尝试从 JVM 中获取最后的汁液,JMeter 的行为可能会出乎意料。 通常,优化场景效果更好。
  16. 优化正则表达式 正则表达式 :写得不好的 会影响 CPU 性能。 尝试查看 正则表达式指南 ,也许你的正则表达式提取器表达式可以缩小。
  17. 使用带有物理硬件的专用负载生成器 :避免使用虚拟机,因为运行这些的机器与其他虚拟机共享资源(尤其是网络)。 专用物理机是确保最大稳定性的最佳选择。
  18. 逐渐增加负载 :缓慢增加模拟负载以避免过快地压倒测试的服务器。 通常,较小的负载测试是针对服务器运行的,以在对其进行测试 进行 预热 之前对其 。
  19. 避免功能模式 :这种运行模式不适合负载测试,因为它在 JTL 结果文件中存储了更多信息。
  20. 将结果存储在 CSV JTL 而不是 XML 中 :XML 需要 JMeter 在磁盘上写入更多 CPU。 此外,它比 CSV 格式更冗长,因此需要更多的磁盘空间。
  21. 在测试期间监控 JMeter 日志 :这可以通过在负载测试期间使用 等工具发送 JMeter 日志来实现 Elastic Stack 。 这样,你可以密切关注每个负载生成器在负载测试期间的行为。
  22. 使用测试元素的命名约定 :这样,你可以快速将结果与业务事务和请求相关联。 使用唯一的名称来防止结果文件中不同测试元素的结果混合。
  23. 避免过于复杂的场景 :你模拟的负载越多,模拟的场景就越不复杂。 复杂的场景难以理解,使得结果更难以解释。 KISS (Keep It Simple And Stupid)是最好的方法。
  24. 使用 Oracle JVM 而不是 OpenJDK :Oracle JVM 最适合运行高要求 JVM 应用程序(如 JMeter)。 Oracle JVM 在压力下通常更稳定。
  25. 在测试期间监控负载生成器 :密切关注每个负载生成器的 CPU/内存/网络使用情况。 有时,由于负载生成器的大小不正确,测试可能会变得异常。 通过监控它们,你可以防止结果被误解:测试可能因为负载生成器不堪重负而出错。
  26. 监控测试服务器 :发现性能瓶颈的关键是监控运行负载测试的测试后端服务器。 你将能够将性能下降与服务器端问题相关联。 这样,你可以更快地解决后端方面的性能问题。 工具 Perfmon 之 推荐使用 类的 。
  27. 首先在内部运行负载测试 :这听起来可能很奇怪,但是负载生成器离测试的服务器越近,影响性能测试结果的因素就越少。 本地负载测试可避免 Internet 连接问题,并可使用大型内部网络(通常为 1 到 10 Gbps)。 一旦服务器在内部测试中表现良好,云测试就可以揭示互联网网络问题。 这样,你可以将服务器问题与网络问题分开。
  28. 避免对第三方服务进行负载测试 :删除对第三方服务(如 Google、Gmail、Facebook、雅虎、Reddit 等)的任何请求,以避免对不属于你自己的服务进行负载测试。 他们可能会禁止你这样做(被视为 DDoS 攻击),并且可能会以错误的方式影响测试结果。
  29. 快速响应时间并不总是意味着快速服务器 :还要检查错误计数。 服务器通常在提供错误页面方面非常快,而在提供有意义的网页时要慢得多。 当你有大量错误时,请确保你不会被出色的响应时间所欺骗。
  30. 扩展 JMeter 既困难又耗时 :虽然运行分布式 JMeter 测试自己似乎很有趣,因为云机器如此便宜,但真正的价值并不存在。 自动发送 JMX、发送 CSV 文件、启动 JMeter 实例、监控一切,然后收集结果并分析它们需要时间。 你的时间也有成本,考虑到这一点。
  31. 避免通过代理进行负载测试 :否则你最终也会对代理服务器进行负载测试。 根据负载,代理可能会在你的服务器之前失败。 避免任何可能影响测试结果的中间网络设备或服务器。
  32. http采样器使用合适的实现

具体调优

包括:

  • 最大堆大小:我们每台机器内存有16GB,可以分配12GB给jmeter,因此把堆大小往上调大为:heap=-Xms1024m -Xmx12288m
  • 假设每个线程需要1MB内存,那么1k线程需要1GB内存,理论上我们设置最大内存为
  • 内存分配率:

接着对测试脚本进行优化,确保

如果http sampler采用httpclient4,经过测试发现性能更高(高25%左右),虽然cpu使用率也更高一些。

采用另外一种GC的方法ConcMarkSweep,下面的命令有待验证:

1
GC_ALGO:="-XX:+UseConcMarkSweepGC" JVM_ARGS="-Dcom.sun.management.jmxremote.port=1098 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xms4g -Xmx12g -XX:NewSize=128m -XX:MaxNewSize=512m -agentlib:jprofilerti=port=8849,nowait -Xbootclasspath/a:/opt/jprofiler12/bin/agent.jar" ./jmeter -Dserver_port=${SERVER_PORT:-1099} -s -j jmeter-server.log "$@"

验证

参考

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021 Johnny Li
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信