k6系列之我的第一个扩展xk6-zap

go mod init

我是直接go mod init xk6-zap的,后来执行上传github后执行xk6 build --with github.com/Mistyrain520/xk6-zap@latest的时候有问题

1
2
3
4
go: k6 imports
github.com/Mistyrain520/xk6-zap: github.com/Mistyrain520/xk6-zap@v1.2.0: parsing go.mod:
module declares its path as: xk6-zap
but was required as: github.com/Mistyrain520/xk6-zap 如何修正这个问题

google之后发现我的mod文件中第一行moudle xk6-zap其实不对。我本地自己打包这样是没问题,但是上传github之后我需要改成github.com/Mistyrain520/xk6-zap

因此建议按照go mod init github.com/Mistyrain520/xk6-zap

开始

我先创建github仓库,拉到本地

1
2
3
4
5
//我本地有两个账号,需要改改
git config user.name "Mistyrain520"
git config user.email 1298616974@qq.com
git config user.name
git config user.email

然后编写代码,过程忽略不说。主要说几个坑。

  • go中导出是按照函数第一个字母大写来导出的,但是实际在xk6中用这个导出的方法,不需要大写。

    1
    2
    3
    4
    //k6扩展中InitLogger
    func (z *ZapLogger) InitLogger(path string, args ...int) *zap.SugaredLogger {}
    //在实际应用中initLogger
    const mylogger = zaplogger.initLogger("./test.log")

    这可能是因为go和js不同吧。执行xk6 build之后,导出的大写实际上应该默认改为小写了。

  • k6的生命周期要熟悉。初始化阶段和setup、 teardown其实是不同的。

如果你在初始化阶段声明const mylogger = zaplogger.initLogger("./test.log"); console.log("@@")。然后你设置VU数为2,你会发现@@其实打印了了不止一遍。
每个VU都会执行一遍初始化以及setup、teardown。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import zaplogger from 'k6/x/zaplogger';
import { sleep } from 'k6';

const mylogger = zaplogger.initLogger("./test.log")
console.log("@@@@@@@@@@")
export default function () {
mylogger.infow("msg", "key", "gagga")
mylogger.infow("msg", "key1", "values1")
sleep(5)
}
//以上代码总共打印了三遍

/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io

INFO[0000] @@@@@@@@@@ source=console
execution: local
script: .\examples\test2.js
output: -

scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

INFO[0000] @@@@@@@@@@ source=console
INFO[0005] @@@@@@@@@@ source=console

data_received........: 0 B 0 B/s
data_sent............: 0 B 0 B/s
iteration_duration...: avg=5.02s min=5.02s med=5.02s max=5.02s p(90)=5.02s p(95)=5.02s
iterations...........: 1 0.198953/s
vus..................: 1 min=1 max=1
vus_max..............: 1 min=1 max=1


running (00m05.0s), 0/1 VUs, 1 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs 00m05.0s/10m0s 1/1 iters, 1 per VU

根据我的测试分析,最后一遍是在sleep之后打印出来的,这一步可能是默认的teardown打印的。但是我加了teardown,结果却打印了四遍。因此猜测本身k6会自己执行一次收尾操作,这次收尾操作和teardown都是可以认为是一个vu,都会执行一遍初始化阶段的代码console.log("@@@@@@")

1
2
3
export function teardown() {
// 什么也不做
}

总结如下

  • k6默认会有开始和收尾的操作,会执行初始化阶段的代码
  • k6的setup teardown都会执行初始化阶段
  • k6的function也就是默认一个VU,都会执行初始化阶段代码

如下这段代码总共打印5次@@@@@@@@

1
2
3
4
5
6
7
8
9
console.log("@@@@@@@@@@")
export function setup() {
}
export default function () {
sleep(5)
}
export function teardown() {
}

  • 调试过程中其实可能导入了其他包,最后上传github之前建议执行go get -u更新所有依赖
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //否则可能会有如下报错
    go: k6 imports
    github.com/Mistyrain520/xk6-zap imports
    go.k6.io/k6/js/modules imports
    go.k6.io/k6/loader tested by
    go.k6.io/k6/loader.test imports
    go.k6.io/k6/lib/testutils/httpmultibin imports
    google.golang.org/grpc/status imports
    google.golang.org/genproto/googleapis/rpc/status: ambiguous import: found package google.golang.org/genproto/googleapis/rpc/status in multiple modules:
    google.golang.org/genproto v0.0.0-20210226172003-ab064af71705 (C:\Users\EDY\go\pkg\mod\google.golang.org\genproto@v0.0.0-20210226172003-ab064af71705\googleapis\rpc\status)
    google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 (C:\Users\EDY\go\pkg\mod\google.golang.org\genproto\googleapis\rpc@v0.0.0-20230525234030-28d5490b6b19\status)
    2023/10/29 15:14:45 [INFO] Cleaning up temporary folder: C:\Users\EDY\AppData\Local\Temp\buildenv_2023-10-29-1514.2545891510
  • 多个扩展打包
    xk6 build --with github.com/Mistyrain520/xk6-zap@latest --with github.com/grafana/xk6-sql
  • 本地打包
    xk6 build --with github.com/Mistyrain520/xk6-zap=.

后续

除了go可以编写打包为k6扩展之外,k6也支持用es6、ts去编译打包后作为模块包给k6引用。
详情点击这里,比如这个check模块包
笔者试过将uuid、winstom打包,但其中曲折比go麻烦不少,且事实上用go来写扩展包应该是效率更好的。像zap包都是高性能和线程安全的。

wsl ubuntu下的编译

  • 首先需要保证有go环境,go version能执行通,默认安装路径是/usr/local/go
  • 接下来下载xk6,执行go install go.k6.io/xk6/cmd/xk6@latest,下载完毕默认安装路径是/root/go/bin
  • 尝试把xk6配置到环境变量上。我试过几次失败了,于是跳过这一步
  • 直接进入/root/go/bin,查看这个目录下有个xk6,直接执行./xk6 build --with github.com/Mistyrain520/xk6-zap@latest --with github.com/grafana/xk6-sql,完成之后目录下多了k6可执行二进制文件

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!