使用k6进行负载测试

k6

k6是一款来自Grafana的开源的负载测试工具。

官方说法中,K6的特点是:

和其它负载工具测试对比

JMeter

Gatling

Vegeta

总结

对于开发者或者具备一些JavaScript编码能力的测试人员来说,k6使用起来非常方便,其性能高,成本低,可以方便地集成进自动化流水线,支持分布式负载

一般使用姿势

k6使用起来非常简单,只需要3步

1. 安装

MacOS下可以通过brew install k6命令安装

Windows下,如果安装了Chocolatey或者winget等包管理工具,可以通过工具命令安装

或者,访问github.com/grafana/k6/releases,下载对应的安装包或可执行文件

2. 编写脚本

import { check } from 'k6';
import http from 'k6/http';
export default function () {
    const url = `${baseUrl}/items`
    const req_body = {
        "foo": "bar",
    };
    const params = {
        headers: {
            'Content-Type': 'application/json'
        }
    };
    const res = http.post(url, JSON.stringify(req_body), params);
    check(res, {
        'status is 200': () => res.status === 200,
    });
};

3. 执行

k6 run --vus 400 --duration 3m mytest.js

(启动400个vu,持续执行3分钟)

等待执行结果:

✓ status is 200

█ setup

checks.........................: 100.00% ✓ 495418      ✗ 0
data_received..................: 116 MB  642 kB/s
data_sent......................: 371 MB  2.1 MB/s
http_req_blocked...............: avg=38.93µs  min=924ns    med=2.45µs   max=80.93ms  p(90)=3.56µs   p(95)=4.48µs
http_req_connecting............: avg=5.88µs   min=0s       med=0s       max=30.2ms   p(90)=0s       p(95)=0s
http_req_duration..............: avg=145.1ms  min=10.55ms  med=109.6ms  max=2.99s    p(90)=296.31ms p(95)=372.08ms
  { expected_response:true }...: avg=145.1ms  min=10.55ms  med=109.6ms  max=2.99s    p(90)=296.31ms p(95)=372.08ms
http_req_failed................: 0.00%   ✓ 0           ✗ 495418
http_req_receiving.............: avg=1.28ms   min=12.33µs  med=307.76µs max=120.82ms p(90)=3.44ms   p(95)=5.25ms
http_req_sending...............: avg=31.82µs  min=7.4µs    med=16.63µs  max=135.44ms p(90)=28.31µs  p(95)=46.41µs
http_req_tls_handshaking.......: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s
http_req_waiting...............: avg=143.79ms min=10.49ms  med=108.24ms max=2.98s    p(90)=294.81ms p(95)=370.19ms
http_reqs......................: 495418  2749.134151/s
iteration_duration.............: avg=145.37ms min=300.04µs med=109.85ms max=2.99s    p(90)=296.56ms p(95)=372.5ms
iterations.....................: 495418  2749.134151/s
vus............................: 400     min=0         max=400
vus_max........................: 400     min=400       max=400

在Kubernetes中进行分布式负载测试

分布式负载测试需要在Kubernetes中安装k6-operator

curl https://raw.githubusercontent.com/grafana/k6-operator/main/bundle.yaml | kubectl apply -f -

安装完成后,需要将测试脚本写入ConfigMap中:

kubectl create configmap mytest --from-file "mytest.js"
script.js

之后,通过在Kubernetes中创建一个类型为K6的资源,来执行测试:

apiVersion: k6.io/v1alpha1
kind: K6
metadata:
  name: mytest
spec:
  runner:
    image: registry.cn-hangzhou.aliyuncs.com/surac/grafana-operator:latest-runner
	# 这个镜像以及下面的镜像是我自己打包的,如果需要用到一些额外的k6扩展,则需要自己打包镜像
  starter:
    image: registry.cn-hangzhou.aliyuncs.com/surac/grafana-operator:latest-starter
  parallelism: 4 #并行实例数,测试任务会分摊到各个实例执行
  script:
    configMap:
      name: mytest.js
      file: mytest.js
kubectl apply -f mytest.yaml

k6-operator发现这个资源被创建后,就会创建1个启动Job和4个执行Job,来执行测试任务,可以通过kubectl get jobs来观察

NAME             COMPLETIONS   DURATION   AGE
mytest-1         1/1           115s       440d
mytest-2         1/1           114s       440d
mytest-3         1/1           79s        440d
mytest-starter   1/1           2s         440d

最后

k6还有许多功能,比如: