专栏文章 推荐一款简单易用线上引流测试工具:GoReplay

狂师 · 2019年11月07日 · 最后由 linxiqin 回复于 2021年05月25日 · 6193 次阅读

一. 引流测试产生背景

日常大部分的测试工作都是在测试环境下,通过模拟用户的行为来对系统进行验证,包括功能以及性能。在这个过程中,你可能会遇到以下问题:

  • 用户访问行为比较复杂,模拟很难和用户行为一致,模拟不够真实;
  • 线下模拟场景有限,会出现业务覆盖不全的情况。

引流测试的出现就是为了解决以上问题,它的本质是:通过把线上的真实流量复制到线下环境,解决测试环境模拟不够真实,或覆盖不够全面的问题

二. 引流测试常见方案

目前不少公司对引流测试进行了实践探索,常见的有以下 4 种引流方式(不限):

上述的几种引流方式各有利弊,有的是需要自己开发相应的工具来支持。而今天给大家介绍的是另外一款简单易用,学习成本低的引流工具 Gor。

三. 推荐一款引流工具:Gor

Gor,又称为 GoReplay,是采用 Golang 编写的一个开源的 HTTP 实时流量复制工具。它只需要在 LB 或者 Varnish 入口服务器上执行一个进程,就可以把生产环境的流量复制到任何地方,比如 Staging 环境、Dev 环境。常用于压测及线上问题复现。

注:Golang 是采用 Gor 实现且开源的,意味着可以方便的集成到自己的架构中,可以用在压力测试平台、实时流量分析、应用层防火墙等方面。

四. Gor 工作流程

监听服务器捕获 http 流量并将其发送到重放服务器或保存到文件,重播服务器将流量转发给给定的地址。

注:Gor 不是代理人,不需要将第三方工具放到关键路径上。相反,Gor 只是默默地分析你的应用程序的流量,并不影响本身程序。

五. Gor 支持的常用功能

  1. Gor 支持流量的放大和缩小、频率限制,这样不需要搭建和生产环境一致的服务器集群也可以正确测试。
  2. Gor 还支持根据正则表达式过滤流量,这意味着可以单独测试某个 API 服务。
  3. Gor 还可以修改 HTTP 请求头,比如替换 User-Agent, 或者增加某些 HTTP Header 。
  4. Gor 还可以把请求记录到文件,以备回放和分析。Gor 支持和 ElasticSearch 集成,将流量存入 ES 进行实时分析。

六. Gor 下载安装

官网下载地址:https://github.com/buger/goreplay/releases 下载最新的 Gor 二进制文件(支持 Windows,Linux x64 和 Mac OS 提供预编译的二进制文件),或者可以自行编译。

获取 gor 版本:https://github.com/buger/goreplay/releases
源码地址:https://github.com/buger/goreplay
官方使用文档:https://github.com/buger/gor/wiki

七. Gor 常用命令用法

可用输入:

  • --input-raw - 用于捕获 HTTP 流量,您应该指定 IP 地址或接口和应用程序端口。有关捕获和重放流量的更多信息。
  • --input-file- 接受之前使用的文件--output-file。更多关于保存和从文件重播
  • --input-tcp - 如果您决定将来自多个转发器 Gor 实例的流量转发给它,则由 Gor 聚合实例使用。阅读关于使用 Aggregator-forwarder 设置。

可用输出

  • --output-http - 重放 HTTP 流量到给定的端点,接受基础 URL。阅读 [关于它的更多信息](重播 HTTP 流量)

  • --output-file - 记录传入的流量到文件。更多关于保存和从文件重播

  • --output-tcp- 将传入数据转发给另一个 Gor 实例,并与其一起使用--input-tcp。阅读关于 Aggregator-forwarder 设置的更多信息。

  • --output-stdout - 用于调试,输出所有数据到 stdout。

更多参数,可查阅官网文档。

八. Gor 常用实践场景

1、流量实时复制引流(--input-raw 拦截端口配合--output-http 输出),例如将本机 80 端口的 HTTP 流量实时复制到 targer_server:8080。

gor --input-raw :80 --output-http "http://target_server:8080"

2、如果目标服务器使用的库与线上机器一样,且只需要引流 Get 方法的请求。

gor --input-raw :80  --http-allow-method GET --output-http "http://target_server:8080"

3、当需要对线上服务进行整体性能压测时,可将线上请求扩大 N 倍,进行引流,将请求扩大 1 倍,也可缩小,调整"|"后面的百分比即可。

gor --input-raw :80  --http-allow-method GET --output-http "http://target_server:8080|200%"

4、只复制某个 URL 请求,--http-allow-url 参数,-http-allow-url 参数可用正则表达式(--output-http-url-regexp 在 gor 0.16 已经过期,使用--http-allow-url 代替)。

gor --input-raw :8080 --http-allow-method GET --output-http "http://target_server:8080" --http-allow-url mall.*hotword

5、多目标服务器的流量复制引流,有点类似 nginx 的 mirror。

gor --input-raw :80 --output-http "http://target_server:8080" --output-http "http://target_server2:8080"

6、将流量转发到多个端点,默认情况下,它会将相同的流量发送到所有输出。

gor --input-tcp :28020 --output-http "http://staging.com"  --output-http "http://dev.com"

7、将相同的流量发送到多个站点,并且平分所有流量。

gor --input-raw :80 --output-http "http://staging.com"  --output-http "http://dev.com" --split-output true

8、HTTP 超时,默认情况下,http 请求和响应的超时时间为 5 秒。你可以像这样覆盖它:

gor --input-tcp replay.local:28020 --output-http http://staging.com --output-http-timeout 30s

9、基本身份验证,如果您的开发或登台环境受基本身份验证保护,那么可以在重放期间注入这些凭据:

gor --input-raw :80 --output-http "http://user:pass@staging.com"

10、性能压力测试

可以将流量复制到文件,然后再对他们进行回放。回放的时候,流量会维持原始的时间间隔。如果你使用了百分比来进行速率限制,那么回放的速率会相应的增加或减少。有了这种速率限制,gor 就可以用来进行压力测试。

gor --input-file "requests.gor|200%" --output-http "staging.com"

目前,input-file 仅在使用基于百分比的限制器时才支持此功能。与默认限制器不同 input-file,它不会降低请求速度,而会减慢速度或加速请求发射。

11 、录制与回放

./gor --input-raw :8000 --output-file=requests.gor

执行录制命令后,将会创建新文件并不断向其写入所有捕获的请求。

12、流量回放,重播来自文件的请求。

./gor --input-file requests.gor --output-http="http://localhost:8001"

您应该看到所有记录到http://localhost:8001的请求,并且它们将以相同的顺序重播,并且与录制的时间完全相同。

gor 的用法也远不止上述提到的这些,更多的应用测试场景,还请读者自行挖掘。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 12 条回复 时间 点赞

线上都已经出现了这种操作了,有问题也在线上环境暴露了,再引流到测试环境的意义是?

狂师 #11 · 2019年11月07日 Author
Karaser 回复

测试环境的业务流量数据往往都过于单一或简单,或者构建数据成本较大,引流的目的,并不是为了等线上出现问题再操作。你可以理解为它是一种让测试环境的业务数据能更贴合生产环境的一种快速实践技术手段。

狂师 回复

新开发或者改动的接口,参数都不同或者没有,怎么引?
只有在接口不变,逻辑改动的时候引流才有意义吧?

我们也是用这个作流量复制。

测试生 回复

嗯,这个还是目前比较常用的一个引流手段。

我们用的 tcpcopy 做引流

simple 回复

嗯,tcpcopy 也是另一种常见的手段,一般如果不想从头自研的话,目前大部分都是基于 lua+nginx、tcpcopy、gor 这三种方式了。

https 的能支持吗?

GoReplay 在别的环境回放的时候,会把中间件 mock 掉么?
如果不 mock 的话,会引起数据不一致的问题,导致回放失败。

提一个小问题哈, 头一次接触流量复制可能问题比较小白, 就是流量复制到测试环境后, 怎么验证产品是正确的没有 bug?

孙高飞 回复

线上和测试环境返回结果对比。这种对读流量很容易实现,但是对于写流量就不 work 了。还有涉及到一些列中间件的 mock,目前最成熟的还是阿里的 doom 及 jvm-sandbox

正好在做这个,想问下,我现在 jpress 分别安装在云服务器和本地(windows)上,我可以把 linux 上的 http 流量抓下来输出到终端或保存为一个文件。现在我想把流量复制到本地,执行命令后,我看不出区别(就是不能像自动化一样,一起动,或者看到成功的信息)我怎么知道他已经把流量复制到我本地,又怎么来判断是否产生 bug

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册