如何使用k6负载测试工具来开发Grafana

298 阅读6分钟

在6月份GrafanaCONline的最后一天,我们的CEO Raj Dutt宣布Grafana实验室已经收购了开源负载测试工具背后的公司k6。事实上,我们与k6的关系早在两年多前就开始了。

在2019年初,我们正在为Grafana 6.0版本用一个短暂的令牌解决方案取代Grafana的 "记住我 "cookie解决方案。在开发过程中,我们想测试一下,当系统处于重载和/或扩展并运行多个Grafana实例时,短命令牌的刷新会有什么表现。因此,我们开始寻找一个开放源码的负载测试工具。

我只有一些使用Locust的有限经验,但它是用Python实现的,而且还需要用Python实现负载测试,而我从来没有用过这种语言。我记得我当时很喜欢的一件事是,它有一个UI来控制和可视化负载测试的结果。

Grafana后端和Grafana实验室的大部分其他软件都是用Go实现的。因此,我们寻找一种工具,它可以像其他Go工具和服务一样简单易行地运行和管理,并且仍然可以用我们许多人已经使用的语言来实现负载测试。

进入k6

经过一番搜索,我偶然发现了k6,它满足了OSS和Go的要求。负载测试是用JavaScript ES2015/ES6编写的--这很合适,因为Grafana的前端/UI已经使用了它,而且包括我在内的一些后端开发者也熟悉它。在试用它之前,我记得我真的被显示该工具的简单性的文档和例子所打动,以及它看起来很容易开始编写和运行一个负载测试。

k6是一个高性能的负载测试工具,可以用JavaScript编写脚本。为了实现这一点,其中一个权衡因素是它不在浏览器中运行,因此它不像网络浏览器那样渲染网页。这种方法的优点是,它比其他基于浏览器的测试工具的资源密集度要低得多,因此更具成本效益。因此,k6负载测试最好是针对HTTP API和/或返回非视觉响应的HTTP端点进行编写,这些响应对机器来说很容易解释,如JSON。当运行k6负载测试时,有大量的选项,但作为一个简化版本,你可以使用一个固定的持续时间或固定的迭代次数,加上一些虚拟用户(VU)来模拟负载。此外,k6支持两种不同的方式来验证负载测试的结果:检查(断言)和阈值(通过/失败)。欲了解更多信息,请参见k6文档

下面是一个基本的k6脚本的样子:

import http from 'k6/http';

import { sleep } from 'k6';



export default function () {

  http.get('https://test.k6.io');

  sleep(1);

}

我开始写一个负载测试,模拟用户加载一个每5秒刷新一次的Grafana仪表盘。这个场景包括一个初始迭代,叫做setup函数,用来登录用户,然后是接下来的迭代,每个迭代提出一个注释请求和20个数据源请求。每个迭代都用检查来验证,例如,用户是用正确设置的登录cookie集来验证的。此外,k6还验证了每个HTTP请求是否默认返回了预期的200 OK状态代码(尽管这一行为可以被改变)。

为了使负载测试代码更容易阅读,提供HTTP客户端与Grafana的登录端点和HTTP API和实用功能进行交互的代码已被提取到一个可重用的模块。目前所有的负载测试都共享这个模块。我们还创建了一个shell-script,作为k6 Docker镜像的一个方便的封装器。它允许我们提供一个API,用于运行具有正常默认值的负载测试,同时允许我们在运行本地与扩展场景时覆盖某些参数。在Grafana GitHub仓库的负载测试目录下查看所有细节和自述。

与我之前使用Locust的经验相比,我非常喜欢k6,它的开发工作流程是为开发者优化的。在终端中运行负载测试,并在一个组织良好的输出中获得即时反馈,而且很容易以文本形式分享,这种能力真的很好,让我作为一个开发者的生活更轻松。

另一个我一开始没有意识到的好东西是在k6负载测试运行时监控Grafana或你的应用程序的能力。我们有一个使用Docker Compose的Grafana高可用性(HA)测试设置。通过这个设置,我们可以扩大我们想要的Grafana实例的数量,使用MySQL或Postgres作为后端数据库,并使用PrometheusLoki来摄取Grafana和数据库的指标和日志。然后我们可以针对这个设置运行我们的k6负载测试,在k6负载测试结果旁边,我们可以可视化存储在Prometheus中的Grafana、Docker和数据库指标,以及存储在Loki中的尾部日志,使我们能够识别潜在的瓶颈和问题,并且/或者帮助我们验证某些负载测试的表现符合预期。

Grafana ❤️ k6

使用k6来验证新的短命令牌解决方案的实施是非常成功的。在实际发货之前,我们成功地发现了代码中的瓶颈和错误。

几个月后,我们得到报告说,升级到Grafana v6.2并结合使用Grafana auth代理,在试图为仪表盘面板加载数据时,出现了很多500内部服务器错误。为了重现这个问题,我们实施了一个auth代理负载测试,制定了一个解决方案,并通过运行负载测试比较结果来验证该解决方案:

下面是一些我们成功使用k6的其他例子:

  • 通过运行现有的负载测试,可以验证一个建议的短命令牌解决方案的改进,减少引入新的bug的风险,并迅速将其发布给终端用户。
  • 通过实现k6负载测试,运行它来测试和调整使用不同索引和重写原始查询的慢速数据库查询的查询性能,提高了数据库查询性能
  • 正如这篇博文中提到的,我们使用k6来研究如何防止DDoS攻击和优化渲染图像的吞吐量。

总结

我们已经从k6负载测试中获得了很多价值,现在k6已经成为Grafana实验室家族的一部分,我期待着与这个工具进行更多的合作。

对于那些在2019年走我们同样道路的人来说,你应该知道k6已经与CI/CD工具很好地整合,k6 Cloud可以用来安排定期的负载测试,这样你就可以关注性能随时间的变化。这应该可以让你更积极主动,更早地发现错误和问题。 我很高兴地报告,Grafana也有一个官方的k6 Cloud插件,所以你可以在Grafana中查看存储在k6 Cloud中的测试结果。另外,你也可以使用k6的Prometheus remote_write功能来发送指标到Grafana Cloud。要了解更多关于使用k6与Grafana的信息,请务必报名参加9月16日的免费网络研讨会,"用Grafana和k6进行负载测试介绍"。