使用 Javascript 进行负载测试
Javascript无处不在!
请告诉我更多……
Node.js 与 Golang
告诉我谁是赢家
结论
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
Javascript无处不在!
或许你不会感到惊讶,JS使我们能够为任何平台构建几乎任何类型的应用程序。
但我以前从未听说过可以使用Javascript 代码来执行负载和性能测试,甚至还可以从这些测试中收集指标来了解应用程序的行为。
请告诉我更多……
赋予我们这种力量的工具是🔧K6🔧。
但这究竟是什么呢?来自K6官方网站:
k6 是一款以开发者为中心的免费开源负载测试工具,旨在让性能测试成为一种高效且愉快的体验。
k6 是用Go编写的,但它公开了一个Javascript API,允许我们编写 javascript 代码与之交互。
安装💾
Node.js 与 Golang
让我们使用k6来比较用 Golang 编写的简单 API 和用 Nodejs 编写的简单 API 的性能。
需要明确的是,该应用会消耗大量的 CPU 资源,这对 Nodejs API 来说是一个劣势😬
这两个应用程序都会计算作为路径参数传递的斐波那契数列的第 n 个值,例如,apiUrl/fibonacci/7必须返回:
{
"fibonacci": 34
}
此外,还有一个健康检查端点:apiUrl/hc我建议您在负载测试的第二分钟手动调用此端点。
测试场景📋
我们正在单独测试一个 API 端点,以观察该端点的性能随时间变化的趋势。具体场景如下:
- 测试开始后的第一分钟,系统将逐步增加虚拟用户数,直至达到 100 个虚拟用户。
apiUrl/fibonacci/9999999每个虚拟用户将每 100 毫秒向端点发出一个 HTTP 请求。- 保持这个姿势
2两分钟。 - 最后时刻,虚拟用户数将降至 0。
- k6 运行上述测试需要 4 分钟。
- 该测试有一个简单的目标,在选项对象中声明:
http_req_duration: ['p(95)<1000']这意味着 95% 的请求必须在 1 秒内完成。
k6-test.js
import http from 'k6/http';
import { sleep } from 'k6';
const SLEEP_DURATION = 0.1;
export let options = {
stages: [
{ duration: "1m", target: 100 },
{ duration: "2m", target: 100 },
{ duration: "1m", target: 0 }
],
thresholds: {
http_req_duration: ['p(95)<1000'] // 99% request must complete below 1s
}
}
const BASE_URL = __ENV.API_BASE === "GOLANG" ? "http://localhost:8080" : "http://localhost:9090"
const HEADERS = { "Content-Type": "application/json" }
export default () => {
http.get(</span><span class="p">${</span><span class="nx">BASE_URL</span><span class="p">}</span><span class="s2">/fibonacci/9999999);
sleep(SLEEP_DURATION);
}
使用 k6 运行负载测试 💪
1.克隆示例代码并执行docker-compose up。两个应用都将公开以下接口:
| 应用程序 | 终点 | 港口 |
|---|---|---|
| Golang | /hc /fibonacci/n |
8080 |
| Node.js | /hc /fibonacci/n |
9090 |
2.您可以同时运行两个测试,打开两个终端,也可以一次运行一个终端,这取决于您。
- 要在项目根文件夹中运行 Golang 负载测试,请执行:
k6 run ./k6-test.js -e API_BASE=GOLANG - 运行 Nodejs 负载测试:
k6 run ./k6-test.js
我知道这只是个很简单的测试,但我喜欢记住这句话:
简单的测试总比不测试好。
告诉我谁是赢家
k6 输出Nodejs应用程序
k6 输出Golang应用程序
- 在负载测试期间,您可以调用两个应用程序的健康检查端点来检查响应时间。
1. 向Node.js发送 HTTP 请求平均耗时 2.5 小时15s,而向Golang 应用 237ms发送 HTTP 请求平均耗时 3.5 小时。2
. 由于 HTTP 请求持续时间较长,在相同时间内,Golang 处理的52103请求数量比 Node.js 多。
Golang 赢了,但怎么赢的?🤔
通过分析测试期间的容器资源使用统计信息,可以看到 Golang 容器使用多个 CPU 来处理请求,而 Nodejs 只使用一个 CPU。
另一点是,它Golang为每个 HTTP 请求使用单独的 goroutine,以并发的方式处理请求。
结论
如果您执行了这两个测试,就会发现 Go 在此场景下优于 NodeJS 。但这是为什么呢?
这两个应用程序的主要任务都是计算斐波那契数列的第 n 个数,而根据第 n 个数的大小,该任务可能会消耗大量的 CPU 资源,而 NodeJS 并不适合处理这类任务。
因此,使用 k6,您可以更早地发现性能下降和问题。您还可以编写压力测试来检查应用程序是否能够逐步扩展其基础设施,从而构建弹性系统和健壮的应用程序。


