吞吐量


如果一个网页应用每秒钟接收到 50 个请求,但是它实际上每秒钟只能处理 30 个,那么另外的 20 个请求就只能在一个队列中等待。在性能测试结果中,吞吐量的表现经常使用 TPS 来表示。

测试策略


可以使用负载测试找到应用的 TPS,其策略是使用一系列的事务组合(平常的和密集的),来看看有多少事务在可接受的时间框架内成功通过。

工具


工具上,可以采用高端专业的工具比如 Visual Studio Team System 中的负载测试功能,当然也可以自己写代码来模拟负载。自己写代码衡量请求的响应时间虽然很容易,但是来模拟负载,就需要太多的工作了。Visual Studio Team System 可以让你挑选一系列的事务组合、模拟网络延时,它还将用户的思考时间也考虑进去了、甚至还有测试迭代等等功能,所以采用这个高大上的工具来做负载测试是非常适合的。

但是,除非是 .NET 技术栈,很少有人会去安装 Visual Studio,且不说安装麻烦,等待时间长,操作上需要太多鼠标点击,各种图形界面操作,非常令人反感。

可能有人会说,有图形界面操作,多么令人感动啊,怎么会令人反感?是的,图形界面显得更友好,但是太多步骤太多动画就不方便快速做一些实验。所以今天特别介绍使用另一个工具:k6,来做同样的事情。相比 Visual Studio,它轻量化,使用简单。但是它没有图形界面,需要写点代码,这可能极度符合另一拨人(包括我)的口味。

k6


image.png
k6 是以开发者为中心,自由开源的负载测试工具,使得性能测试更有效率的同时还让使用者感到极度舒适。其特性有:

  • 命令行工具和对开发者友好的开放接口
  • 支持 JavaScript ES2015/ES6 脚本
  • 对自动化友好,支持自定义检查和定义阀值

k6 不是什么


虽然 k6 是一个高性能负载测试工具,可以使用 JavaScript 编写测试脚本,但是为了实现这些特性,不得不在架构设计上做一些取舍:

  • 并不在浏览器里运行
    由于跳过了浏览器,k6 对系统资源的消耗大幅度降低,让工具自身显著高效。尽管如此,仍然可以使用 k6 来做网站的负载测试,甚至可以从录制好的用户会话中创建出测试。
  • 并不在 NodeJs 环境里运行
    JavaScript 在整体上并不适合高性能场景。为达到最高的性能,这个工具采用 Go 语言编写,嵌入了 JavaScript 运行时从而让测试脚本的编写变得容易。如果你要加载 npm 模块或者使用 NodeJs API 的库,你可以使用 webpack 打包 npm 模块然后在测试中加载它们。

k6 的负载测试宣言

  • 简单的测试胜过没有测试
  • 负载测试应该面向目标
  • 负载测试应该由开发者执行(有启发!颠覆三观吗?)
  • 对开发者的体验特别重要
  • 只在预生产环境做负载测试

k6 的安装


详见官方文档,如果是 mac,推荐如下方式: shell brew install k6

快速测试一个 API 的吞吐量能力


首先,确保是非生产环境。其次,找一个终端节点,这里拿一个只返回 OK 的健康检查接口为例。

然后,写一个 JavaScript 脚本,命名为 k6.js,如下所示: javascript import http from k6/http; import { sleep } from k6;

export let options = { stages: [ { duration: 2m, target: 100 }, // 低于正常的负载场景 { duration: 5m, target: 100 }, { duration: 2m, target: 200 }, // 正常负载场景 { duration: 5m, target: 200 }, { duration: 2m, target: 300 }, // 临界点附近 { duration: 5m, target: 300 }, { duration: 2m, target: 400 }, // 超出临界点 { duration: 5m, target: 400 }, { duration: 10m, target: 0 }, // 缩小规模,恢复阶段 ], };

export default function () { const BASE_URL = http://localhost:3000; // 确保不要用生产环境 URL

let responses = http.batch([
    [
        GET,
        ${BASE_URL}/v2/health,
        null,
        { tags: { name: Health Check } },
    ],
]);

sleep(1);

}

然后从命令行运行 k6: shell k6 run k6.js

比如会得到这样的结果: shell running (38m00.7s), 000/400 VUs, 514826 complete and 0 interrupted iterations default ✓ [======================================] 000/400 VUs 38m0s

data_received..............: 256 MB 112 kB/s
data_sent..................: 44 MB  19 kB/s
http_req_blocked...........: avg=9.88µs  min=0s med=3µs    max=2.29s    p(90)=5µs    p(95)=7µs
http_req_connecting........: avg=261ns   min=0s med=0s     max=1.09ms   p(90)=0s     p(95)=0s
http_req_duration..........: avg=2.12ms  min=0s med=1.18ms max=267.25ms p(90)=4.31ms p(95)=5.85ms
http_req_receiving.........: avg=28.12µs min=0s med=29µs   max=2.66ms   p(90)=46µs   p(95)=55µs
http_req_sending...........: avg=12µs    min=0s med=12µs   max=2.57ms   p(90)=20µs   p(95)=25µs
http_req_tls_handshaking...: avg=0s      min=0s med=0s     max=0s       p(90)=0s     p(95)=0s
http_req_waiting...........: avg=2.08ms  min=0s med=1.12ms max=267.2ms  p(90)=4.25ms p(95)=5.8ms
http_reqs..................: 514826 225.72893/s
iteration_duration.........: avg=1s      min=1s med=1s     max=3.3s     p(90)=1s     p(95)=1s
iterations.................: 514826 225.72893/s
vus........................: 1      min=1   max=400
vus_max....................: 400    min=400 max=400

从上面的报告中可以得到一个大概的结论:TPS 约等于 226,即每秒钟可以处理大约 226 个请求。

总结


本文介绍了一种区别于 Visual Studio Team System 以及 JMeter 这种基于图形界面的负载测试工具,并详细展示了一个最基本的使用步骤。可见真的是非常简单,对开发者友好,特别适合自动化。另外,特别喜欢 k6 的负载测试宣言,首先喜欢它的对开发者友好特性,其次被它的负载测试应该由开发者执行这一条震撼到了。希望对你有启发,欢迎留言分享你是怎么做负载测试的。