k6 是 Grafana 家出品的压测工具,可以在本地搭配 prometheus, grafana 这样的工具来制作报告,也可以在测试过程将状态输出到 k6 cloud,然后在云端查看报告。产品相关的介绍可以直接访问官网,以及一些相关文章来了解吧。
官网提供了一个简单的例子介绍使用 k6 来做 gRPC 的测试
import grpc from 'k6/net/grpc';
import { check, sleep } from 'k6';
const client = new grpc.Client();
client.load(['definitions'], 'hello.proto');
export default () => {
client.connect('grpcbin.test.k6.io:9001', {
// plaintext: false
});
const data = { greeting: 'Bert' };
const response = client.invoke('hello.HelloService/SayHello', data);
check(response, {
'status is OK': (r) => r && r.status === grpc.StatusOK,
});
console.log(JSON.stringify(response.message));
client.close();
sleep(1);
};
但是在这个例子中,每次循环客户端都会关闭连接。官方文档好像没有直接提及的地方,搜了下 issues,发现可以借助 __ITER
这个变量做判断。
// ref: https://github.com/grafana/k6/issues/1846
import grpc from 'k6/net/grpc';
import { check, sleep } from "k6";
export let options = {
vus: 50,
duration: '10s'
}
let client = new grpc.Client();
client.load([], "chat.proto")
export default () => {
if (__ITER == 0) {
client.connect("127.0.0.1:3000", { plaintext: true })
}
const response = client.invoke("go.grpc.http.muxer.com.chat.v1.ChatService/SayHello", {
body: 'hi'
})
check(response, { "status is OK": (r) => r && r.status === grpc.StatusOK });
}
或者
// ref: https://community.k6.io/t/reconnect-in-grpc/1286/4
import grpc from 'k6/net/grpc';
import { sleep } from 'k6';
export const options = {
iterations: 10,
};
let client = new grpc.Client();
// Download addsvc.proto for https://grpcb.in/, located at:
// https://raw.githubusercontent.com/moul/pb/master/addsvc/addsvc.proto
// and put it in the same folder as this script.
client.load(null, './addsvc.proto');
let connected = false;
export default function () {
if (!connected) {
console.log(`Connecting in iteration ${__ITER}...`);
client.connect('grpcb.in:9001', { timeout: '5s' });
connected = true;
}
let response = client.invoke('addsvc.Add/Sum', {
a: 1,
b: 2
}, { timeout: '5s' });
//console.log(JSON.stringify(response));
if (response.status == grpc.StatusDeadlineExceeded) {
console.log(`${__ITER} timed out, disconnecting...`);
connected = false;
client.close(); // not really needed, I think, but just in case
//TODO: emit some error metric?
return;
}
console.log(`${__ITER} result: ${response.message.v}`);
sleep(3);
}