【k6】gRPC服务性能测试

* Simon Aronsson(开发者推广大使)著,Ng Wai Foong 译
* 原文网站:k6官方网站
* 原文链接 https://k6.io/blog/zh/performance-testing-grpc-services/

🎉 v0.29.0的新功能

v0.29.0包含许多特别有用的功能。 查看发布版本通知以了解更多详细信息!

什么是gRPC?

gRPC是一个轻量级的开源的RPC框架,它最初是由谷歌(Google)开发的,2016年8月发布了1.0版本。此后,它得到了广泛的关注和采用。

与作为人类可读的文本传输的JSON相比,gRPC是二进制的,使其传输速度更快,而且它的结构更紧凑。在我们看到的基准测试中,事实证明gRPC比传统的基于JSON的REST快得多。

按照Auth0的基准,性能高达6倍,而其他基准,如Alex Pliutau的基准Ruwan Fernando的基准,则显示出高达10倍的改进。

对于分布式系统和涉及客户端与服务器之间大量通信的系统,这些改进意义重大,差异不仅在基准上明显,而且从终端用户的角度来看也非常明显

API类型

gRPC支持四种不同类型的RPC,一元(unary)、流媒体服务器(server streaming)、流媒体客户端(client streaming)和双向流(bi-directional streaming)。实际上,消息是使用相同的连接进行复用的,为了简单起见,下面的gRPC服务模型图中并未说明这个概念。

一元

一元的方式与常规函数调用相同,客户向服务器发送一个请求,服务器回复一个响应。

一元

流媒体服务器

在流媒体服务器模式下,客户向服务器发送一个请求,服务器回复多个响应。

流媒体服务器

流媒体客户端

流媒体客户端模式与流媒体服务器模式相反,客户向服务器发送多个请求,服务器回复一个响应。

流媒体客户端

双向流

在双向流模式下,客户或服务器是可以互相发送多个信息。

双向流

proto定义

.proto文件中描述了gRPC相关的消息和服务,包含了Protocol buffers或protobuf和它的定义。然后,定义文件被用来生成可被发送方和接收方使用的代码,作为通过这些信息和服务进行交流的合同,由于gRPC使用的二进制格式缺乏自描述属性,所以需要这个文件来解释消息。

在本文中,我们将使用hello.proto定义,您可以通过k6的grpcbin网页下载它,有关如何构建自己的gRPC proto定义的详细信息,请参考官方gRPC文档.

// ./definitions/hello.proto

// based on https://grpc.io/docs/guides/concepts.html

syntax = "proto2";

package hello;

service HelloService {
  rpc SayHello(HelloRequest) returns (HelloResponse);
  rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
}

message HelloRequest {
  optional string greeting = 1;
}

message HelloResponse {
  required string reply = 1;
}

引言

在k6 v0.29.0中,我们很高兴为gRPC通信引入一个原生客户端,在此版本中,我们为一元模式提供了良好的支持,如果其他模式对您有用,我们想进一步了解您的用例,这样以来我们可以为您优先考虑这些功能。

目前k6中使用原生客户端的gRPC API如下所示:

函数说明
Client.load(importPaths, …protoFiles)为gRPC请求加载并解析给定的协议缓冲区定义。
Client.connect(address [,params])打开与gRPC服务器的连接
Client.invoke(url, request [,params])对服务进行一元RPC并返回响应
Client.close()关闭与gRPC服务的连接。

创建测试

gRPC模块是一个单独的包,可以从您的测试脚本中以k6/net/grpc的形式调用,在调用之前,我们必须创建一个客户端的实例,客户端实例化和.load操作仅在测试初始化时才能使用,例如直接在global范围内。

import grpc from 'k6/net/grpc';

const client = new grpc.Client();

接下来,我们将为要测系统加载一个.proto定义。在本文中,我们将使用k6 grpcbin,您可以使用自己的请求和响应服务,但请记住:“在测试时提供相应的.proto定义,.load()函数接收两个参数,第一个是proto文件路径数组,第二个是要加载的文件名。”

import grpc from 'k6/net/grpc';

const client = new grpc.Client();
client.load(['definitions'], 'hello.proto');

完成后,我们将继续写我们的测试脚本。

import grpc from 'k6/net/grpc';

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);
};

接下来,我们看一下以上的脚本以了解更多,我们首先调用.connect()函数连接到我们的测试系统,默认情况下,客户端会将plaintext参数设置为false,仅允许您使用加密的连接,如果您想连接到一个没有SSL/TLS的服务器,您只需将参数更改为true

继续创建要发送到grpc服务器的对象,至于SayHello,我们可以用greeting参数指定greeting地址。

接下来,我们使用proto文件中所述的语法<package>.<service>/<procedure>调用远程过程,该调用是同步进行的,默认超时时间为60000 ms(60秒),你可以通过在.connect()的config对象中加入timeout来改变超时时间,例如'2s'为2秒。

一旦我们收到服务器的响应,就意味着程序执行成功,k6的grpc模块包含了用于这种比较的常量,在此处列出

响应状态grpc.StatusOK相当于HTTP/1.1中的200 OK,使用它进行比较可确保调用成功完成。

然后,我们将记录响应消息,关闭客户端连接并进行sleep一秒钟。

运行测试

这个测试可以像其他测试一样运行,但你需要至少v0.29.0版本才能运行gRPC模块,运行以下命令以检查k6版本。

$ k6 version
k6 v0.29.0 ((devel), go1.15.3, darwin/amd64)

如果版本低于v0.29.0,请更新k6,您可以在此处找到安装说明。

完成后,继续运行我们的测试:

$ k6 run test.js


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

  execution: local
     script: /Users/simme/code/grpc/test.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] {"reply":"hello Bert"}                        source=console

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

    ✓ status is OK

    checks...............: 100.00% ✓ 1   ✗ 0
    data_received........: 3.0 kB  2.1 kB/s
    data_sent............: 731 B   522 B/s
    grpc_req_duration....: avg=48.44ms min=48.44ms med=48.44ms max=48.44ms p(90)=48.44ms p(95)=48.44ms
    iteration_duration...: avg=1.37s   min=1.37s   med=1.37s   max=1.37s   p(90)=1.37s   p(95)=1.37s
    iterations...........: 1       0.714536/s
    vus..................: 1       min=1 max=1
    vus_max..............: 1       min=1 max=1

从输出结果来看,我们的脚本运行正常,服务器的响应为{"reply":"hello Bert"}Bert是我们在请求中发送的参数,我们也可以看到,check成功了,也就是说服务器响应了200 OK

摘要

在本文中,我们介绍了gRPC的一些基本原理以及如何使用它,我们还了解了k6 v0.29.0版本中引入的gRPC客户端。然后,我们创建了一个
测试脚本来展示这个功能。

本篇gRPC负载测试教程就到此结束了。感谢您的阅读!

参阅

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值