k6是GitHub上提供的开源负载测试工具。它是用Go编写的,并运行用JavaScript编写的测试脚本。它受到了开发人员,测试人员和DevOps团队的强烈兴趣,并拥有超过4400名GitHub明星。k6是命令行驱动的,测试结果输出到stdout或结果分析工具,如Load Impact Insights。css
JMeter也是一个开源负载测试工具,已存在多年。它很是受欢迎,拥有数千名用户。它是一个Java应用程序,JMeter GUI用于建立测试脚本。此外,一些脚本语言可用于编写JMeter函数,包括Java,Groovy和JavaScript。Groovy已成为推荐的默认选项。可是,只能从命令行执行负载测试运行。java
在“大卫与歌利亚”的方式中,让咱们看一下在k6中比在JMeter中更容易作的事情的几个例子。程序员
在JMeter中:shell
添加Beanshell Postprocessor做为请求的子项,返回您要查找的响应。浏览器
将代码 vars.put(“response”, new String(data));
放入PostProcessor的“脚本”区域。 服务器
请根据${response}
须要参考提取的值 。网络
在k6中,使用如下测试脚本代码:架构
let response = http.get(“http://javame.cnblogs.com/”);
在这两种状况下,数据最终都在响应变量中。主要区别在于您必须在JMeter中向请求添加Beanshell PostProcessor,而后才能添加代码段。
在JMeter中:并发
在测试下建立一个新的Response Assertion。在断言的“要测试的响应字段”部分中,确保选中“忽略状态”框。负载均衡
而后,您能够添加其余断言,例如将“要测试的响应字段”中的无线电设置为“响应代码”,并将“要测试的模式”设置为404。
图1:显示如何设置响应断言的JMeter GUI。
在k6中,使用如下测试脚本代码:
let response = http.get(“http://some.url/”); check(res, { "Status is 404": (r) => r.status === 404 });
这里的主要区别在于,在JMeter中执行此操做须要您单击GUI并在输入字段中填入值,而使用k6则须要编写几行代码。您能够在版本控制系统(VCS)中轻松跟踪和管理k6 JavaScript加载测试代码,就像您的应用程序代码同样。
例如,假设您要调用logTransaction()
150个不一样测试配置中的一个文件中定义的 函数。
在JMeter中:
将该行添加 beanshell.sampler.init=BeanShellSampler.bshrc
到user.properties文件(位于JMeter安装的“bin”文件夹中)。
将logTransaction函数放在BeanShellSampler.bshrc文件中(相同位置,JMeter的“bin”文件夹)。
下次启动JMeter时,您能够在任何脚本中从任何Beanshell Sampler调用该函数。
在k6:
将logTransaction()函数放在JavaScript文件中,例如“logTransaction.js”
使用如下语句在任何脚本中导入该函数:从“/path/to/logTransaction.js”导入{logTransaction};
在k6中,任何Javascript文件均可以直接用做可导入模块,它容许您以任何方式组织文件。您还能够直接经过网络导入模块:
import { logTransaction } from "s3.amazonaws.com/path/to/logTransaction.js";
除了标准的ES6 JavaScript API以外,k6还捆绑了API来处理Cookie,加密,编码,环境变量,HTML表单,HTML解析,多部分请求,TLS客户端证书,TLS密码和版本等等。
例如,您可能但愿使用两个参数测试servlet:X和Y,其中X和Y是0到100之间的随机数。您须要一个嵌套循环,以下所示:
for(int x = 0 ; x <= 100 ; x ++) for(int y = 0 ; y <= 100 ; y ++) servlet ?param1 = x &param2 = y
在JMeter中:
您的架构可能以下所示:
Thread Group User Defined Variables maxX = 100 maxY = 100 Loop Controller X Loop Count: ${__BeanShell(Integer.parseInt(vars.get("maxX"))+1)} Counter X Start: 0 Increment: 1 Maximum: ${maxX} Reference Name: loopX Loop Controller Y Loop Count: ${__BeanShell(Integer.parseInt(vars.get("maxY"))+1)} Counter Y Start: 0 Increment: 1 Maximum: ${maxY} Reference Name: loopY YOUR HTTP Request servlet?param1=${loopX}¶m2=${loopY} . . .
在k6:
使用如下脚本代码:
for(var x = 0 ; x <= 100 ; x ++) for(var y = 0 ; y <= 100 ; y ++) http.get(“http://some.domain/servlet?param1 =”+ x +“¶m2=”+ y);
固然,执行更复杂的逻辑分支是基于GUI的方法与直接在代码中编写逻辑相比常常变得很是笨重的地方。k6解决方案与用于描述问题的伪代码很是类似。
咱们一般但愿并行发出多个请求,就像浏览器在获取网页时所作的那样。这使得服务器上的压力比每一个虚拟用户一次只发出一个请求要多得多。
在JMeter中:
JMeter提供同步计时器,容许对请求进行分组,以便它们能够在同一时刻执行。只需在测试计划中添加同步计时器,并确保:
它在两个请求中都处于同一级别
线程组中的虚拟用户数> = =同步计时器中设置的数量
在k6:
使用此 http.batch()
功能可并行发出多个请求。例如:
http.batch([ "http://test.loadimpact.com", "http://test.loadimpact.com/style.css", "http://test.loadimpact.com/images/logo.png" ]);
上述“解决方案”不具备100%的可比性。在JMeter状况下,咱们仍然只容许每一个虚拟用户(VU)一次发出一个请求。这意味着JMeter VU不是“真实用户”的彻底准确模型。单我的类用户将使用他们的Web浏览器同时发出多个请求,而JMeter VU一次只发出一个请求。
相反,JMeter所作的是同步VU,以便它们在同一时间发出请求。(对我来讲彷佛不太有用 - 总吞吐量可能会降低,由于某些VU必须等待其余VU完成请求)。
另外一方面,在所示的示例中,k6将容许每一个VU打开三个并发TCP链接,所以可以并行获取这三个项目,就像Web浏览器同样。这意味着在k6状况下,100个VU能够并行获取300个项目。在Jmeter状况下,100 VU将并行获取100个项目。(注意:还有一个名为Parallel Controller的 JMeter扩展可用于建立并行请求)。
推荐阅读: