Gatling vs Jmeter - 每个请求的响应时间差别很大

时间:2017-07-19 01:16:45

标签: jmeter load-testing gatling

我使用Firefox创建了完全相同的演示场景(在网站主页上登陆)并使用Gatling和Jmeter来测试工具。

当我用500 VU执行它们(逐个)30秒时,响应时间(带加特林的800毫秒和Jmeter超过3000毫秒)之间的差异很大,而JMeter显示超过29的失败%虽然加特林仅显示1%

哪一个值得信任?

由于申请仍处于开发阶段,Gatling似乎不可靠,因为我们知道响应时间通常约为2.5秒。

4 个答案:

答案 0 :(得分:6)

不要相信他们中的任何一个。我的期望是,使用JMeter,您不仅记录了主要请求(登陆网站主页),还记录了一系列对所谓“嵌入式资源”的请求 - 图像,脚本,样式等,Gatling不记录这种形式的请求。

这非常重要,因为通常这些嵌入式资源比主响应“更重”,因此您需要注意这一点。

  1. 不记录对嵌入资源的调用。真正的浏览器并行下载它们(主要请求后跟并发调用来获取它们)
  2. 配置负载测试工具以自动获取嵌入资源。

  3. 不要忘记缓存。真正的浏览器下载这些图像,脚本和样式,但只执行一次,实际上没有进行后续请求,从浏览器的缓存中返回资源。

  4. 有关详细信息,请参阅Web Testing with JMeter: How To Properly Handle Embedded Resources in HTML Responses,本文是面向JMeter的,但在Web应用程序性能测试方面,相同的建议适用于任何负载测试工具。

答案 1 :(得分:0)

您似乎已经回答了自己的问题,因为jMeter(3000ms)的响应时间接近您自己静止(2500ms)的观察响应时间。

对于每个负载提供程序(jmeter vs gatling),您应该将负载测试日志与来自Web服务器的日志合并,并绘制来自负载提供程序与Web服务器的响应时间。

哪个图表的值最接近,这是我接受的值。

答案 2 :(得分:0)

  • 饱和负载发生器。为两个样本运行单个虚拟用户,以便为单个用户性能建立基线。您可以通过查看HTTP日志中的w3c时间字段来备份它。如果一致,那么你很可能会看到饱和负载发生器。
  • 测试控制元素。我假设您使用单个负载生成器进行测试。添加第二个控制负载生成器,以检查两个工具之间资源成本差异的主机上的本地问题。在此控件上,Load Generator包括您选择运行的每种类型的单个虚拟用户。如果您的控制组和非控制组以相同的速率降级,那么您就会遇到应用程序问题。如果它们以不同的速率降级,即非控制组较慢,那么您就会遇到特定于负载生成器的问题。您还可以使用绑定到控制负载生成器和非控制生成器的http w3c时间日志字段来查找常见请求(例如foo.html),以检查性能差异。
  • 苹果到Tangelos。如前所述,你确定你的计时完全相同。刷新HTTP日志。执行每个工具虚拟用户类型的单个样本。转储日志并将工具1与工具二进行比较。市场上的每个工具对于根据工具开发人员的需求实现重放的浏览器的方式略有不同。理解这些差异及其如何影响时间记录数据的收集和报告是值得的。
  • 加速。 500位用户持续30秒表明没有提升。这是一个糟糕的测试过程问题,相当于服用一个teetotaler和一瓶伏特加,并在一次燕子结合。您希望了解资源的分配方式以及响应时间差异中的转折点 - 曲线中的拐点。这通常会导致外部方进行负载测试的审核失败 - 没有上升或下降。
  • 检查思考时间和起搏延迟。如果没有,那么您通常无法信任任何工具的结果,因为虚拟用户会折叠客户端 - 服务器模型,该模型期望客户端处理数据的请求之间的延迟,无论是软件客户端还是有机客户端在屏幕和键盘之间循环。

答案 3 :(得分:0)

回应@DmitriT第1点和第2点。

通过gatling,还有另一种以更加可控的方式下载资源的方法:使用 .resources()方法,并列出尽可能多的http("")请求你想要的,它们都将并行执行。为了使其更加逼真,将它与HttpProtocolBuilder设置相结合,例如: .maxConnectionsPerHostLikeChrome 更接近现实。我使用这种方法,因为我的资源也可能有来自先前请求的动态链接,例如:

With gatling there is another way of downloading resources in a more controlled way:  User the **.resources()** method, and list as many http("") requests as you want, they will all be executed in parallel. And to make it more realistic, combine it with HttpProtocolBuilder settings like : **.maxConnectionsPerHostLikeChrome** to be closer to reality.    I use this approach since my resources might also have dynamic links got from previous requests, ex :  `tryMax(1) {
  group("<-- EMP : Login Page -->") {
    exec(
      http("EMP : Login Page - login.html ")
        .get("/admin-ng/login.html")
        .check(regex("/admin-ng/scripts/login.[^\"]*.js").find.saveAs("login_js"))
        .check(regex("/admin-ng/login.[^\"]*.css").find.saveAs("login_css"))
        .check(regex("/admin-ng/scripts/loginVendors.[^\"]*.js").find.saveAs("loginVendors_js"))
        .resources(
          http("EMP : Login Page => Asset 1 - login.xxx.css")
            .get(session => session("login_css").as[String])
            .check(regex("([^\\.]*?\\.woff2)").findAll.saveAs("listOfFontsWoff2"))
            .check(regex("([^\\.]*?\\.woff(?=[^2]))").findAll.saveAs("listOfFontsWoff")),
          http("EMP : Login Page => Asset 2 - login.xxx.js")
            .get(session => session("login_js").as[String]),
          http("EMP : Login Page => Asset 3 - loginVendors.xxx.js")
            .get(session => session("loginVendors_js").as[String])
        )
    )
      .exec(
        http("")
          .get("")
          .silent
          .resources(
            http("EMP : Login Page => Asset 4 - .min.js")
              .get("/nr-spa-974.min.js"),
            http("EMP : Login Page => Asset 5 - woff2 (index: 3)")
              .get(session => session("listOfFontsWoff2").as[Seq[String]].apply(3)),
            http("EMP : Login Page => Asset 6 - woff2 (index: 2)")
              .get(session => session("listOfFontsWoff2").as[Seq[String]].apply(2)),
            http("EMP : Login Page => Asset 7 - woff2 (index: 5)")
              .get(session => session("listOfFontsWoff2").as[Seq[String]].apply(5))
          )
      )
  }
}`

此代码分两个阶段执行,与浏览器相同:

  1. 网页的主链接,其中包含一些指向JS和CSS资源的链接,我提取它们,并在.resources()方法中并行下载它们。
  2. 然后在下一阶段我下载从以前的资源中提取的资源,在本例中是login_css
  3. 通过这种方式,我可以获得真实浏览器非常接近的时间(因为它不会100%准确,无论使用哪种工具,它们中的每一个都将缺少您最终将要面对的特定区域)

    请记住在Gatling中使用group()方法,因为它会将报告下的所有请求和资源并行请求计为一个实体(如从a到z加载的网页),并带有报告中的选项如果需要,单独查看该组的子请求