这个问题的标题代表了我主要关心的问题,但如果你继续读下去问题部分中,您将发现一些有关我们设置的背景信息...这些背景信息可能相关/有用,也可能无用。
问题
我们正在使用以下方法对应用程序进行压力测试加特林并在单身的机器。我们发现我们的应用程序能够应对压力工具产生的高负载;但是,它无法应对来自真实用户的相对较低的负载。
我的问题是:当从单台机器/操作系统向应用程序发出并发请求时,与来自多台机器的并发请求(即普通用户使用他们的网络浏览器)相比,会发生什么样的操作系统/网络级别的优化或简化?
背景
我们有一个 Tomcat 应用程序通过 AJP 位于 Apache 后面,而 AJP 本身又通过端口 80 位于 Citrix Netscaler 后面(我们还计划将 Apache 排除在外,但那是另一回事......)。
我们的应用程序在相对较低的负载下(apache 和 tomcat 之间建立了 CLOSE_WAIT 连接)一直处于停滞状态,我们正在对其进行负载测试以解决该问题。我们的 SQLServer 实例中经常出现死锁,因此我们决定从那里开始。为了复制问题并随后测试我们的修复,我们使用一台机器通过 Gatling 生成负载。
刚开始时,我们能够使用该工具可靠地复制死锁。经过一些优化后,死锁消失了,CLOSE_WAIT 连接也消失了。然后,我们将应用程序推到我们非常满意的负载,并且它运行起来没有任何重大故障。
不幸的是,当修复程序应用于生产系统时,我们仍然看到相同的原始行为。这让我怀疑压力工具产生的负载是否不能很好地代表现实世界中实际发生的情况,因为它来自单一来源,而不是分布在互联网上的许多不同客户端。
答案1
单个负载生成器可能比分散的客户端更好地完成连接池工作;例如更好地利用 Keepalive。这样可以通过更少的连接处理更多的请求。
如果涉及循环 DNS,它将倾向于只命中其中一个 DNS 目的地,而不是将负载分散到所有目的地。一些负载平衡器根据客户端 IP 做出粘性决策,在这种情况下,客户端 IP 是静态的。
您的负载生成器可能有一个受限的执行池(例如,200 个“用户”),因此响应延迟会导致用户速度变慢,而现实世界中则有大量用户不会耐心等待其他用户完成。
答案2
如果不了解 Gatling 测试场景,很难坚持做任何事情。只是“盲目”:您的 Gatling 测试无法准确代表真实用户,即
- 真正的浏览器会下载嵌入到页面中的外部资源,即图片、脚本和样式,并使用并发线程池执行此操作。如果您的 Gatling 测试缺失推断Html资源方法可能会出现这样的情况:来自 Gatling 的负载比坐在真实浏览器后面的真实用户所进行的负载要小得多
DNS 缓存。由于 DNS 名称缓存在 JVM 级别,Gatling 可能仅命中一个 IP 地址。根据Gatling 常见问题解答:
基本上,Gatling/JVM 的 DNS 缓存必须调整。一个解决方案是添加
-Dsun.net.inetaddr.ttl=0
到命令行。AJAX 请求。Gatling 不执行客户端 JavaScript,因此如果您的应用程序基于 XMLHTTP 请求构建,则 Gatling 访问页面时不会触发这些请求。如果您的应用程序使用某种形式的 AJAX,则需要手动处理它们
所以我建议参考如何使JMeter的行为更像真正的浏览器并实施等效的 Gatling 设置,好像负载测试不代表真实生活中的负载,运行这样的测试没有多大意义。