goreplay 使用经验

简介:

测试 HTTP 服务,为了覆盖更多的场景,可以考虑录制线上流量,在测试环境进行重放。之前用 tcpcopy 比较多,最近遇到一些需求,需要在 HTTP 层做一些过滤,例如只录制指定 URL 的请求。

经过调研,发现 goreplay,其前称是 gor,很适合这个场景,有以下优点。

  1. 支持 HTTP 请求的录制和重放,可以在线上录制请求,在测试环境进行重放。
  2. 支持 HTTP 层面的流量过滤,可以只挑选我们感兴趣的流量。
  3. 支持请求放大,用于性能测试。

1. 用法

免 root 运行,抓包并不需要 root 权限,同样的方法适用于 tcpdump,其实 goreplay 和 tcpdump 一样,都用 libpcap 来抓包。

$ sudo setcap "cap_net_raw,cap_net_admin+eip" ./goreplay

抓取 80 端口的 HTTP 请求,只抓请求 URL 是 /api/v1 的,并输出到终端。这个比 tcpdump 更直观,打印到终端的是我们熟悉的 HTTP 协议。

第一行是 goreplay 自定义的 header,平常使用可以不必理会,不是实际抓到的包,从第二行开始才是实际抓到的包。

$ ./goreplay --input-raw :80 --http-allow-url '/api/v1' --output-stdout

抓取 80 端口的所有请求,并保存到文件。实际会分批保存为 request_0.gor,request_1.gor 这种文件名。

$ ./goreplay --input-raw :80 --output-file 'request.gor'

重放请求,例如 host2.com 是我们的新机房域名。这种重放,会根据请求的时间戳,按照抓取时的请求顺序重放。

例如抓取的时候,第一秒 10 个请求,第二秒 20 个请求,那么重放的时候,也会按照这个顺序。并且读完 request.gor 文件,就会停止。

上面我们看到了 goreplay 自定义的 header,其第三个字段,是一个纳秒级的时间戳,根据这个来保证重放的顺序和速率。

$ ./goreplay --input-file 'request.gor' --output-http 'http://host2.com'

如果是性能测试,可以不考虑请求的顺序和速率,并且要求无限循环。

# --input-file 从文件中获取请求数据,重放的时候 100x 倍速
# --input-file-loop 无限循环,而不是读完这个文件就停止
# --output-http 发送请求到 http://host2.com
# --output-http-workers 并发 100 发请求
# --stats --output-http-stats 每 5 秒输出一次 TPS 数据
$ ./goreplay --input-file 'request.gor|10000%' --input-file-loop --output-http 'http://host2.com' --output-http-workers 100 --stats --output-http-stats

更多的命令行参数及用法,可以查看 goreplay 源码的 settings.go 文件。

2. 坑

使用过程中遇到的坑。

  1. 如果 HTTP 请求不符合规范,可能会抓不到包。遇到过 HTTP 请求头里面的 Content-Length 不等于实际的 Body 大小,goreplay 认为其请求未结束。
  2. input-file 是单 goroutine 在跑,会有性能瓶颈。测试的时候,读取的 RPS 在 1.7w - 1.8w 左右,如果压测需求大于这个,需要开多个进程同时跑。

3. 深入

goreplay 是用 golang 编写的,抓包的时候调用 gopacket,后者通过 cgo 来调用 libpcap。从编译开始,从源码层面学习一下其实现。

TL;DR

3.1 编译

由于 goreplay 使用了第三方 C 代码,不能使用 Go 的交叉编译功能来跨平台编译。只能在 Linux 下编译 Linux 使用的可执行文件。

在 Redhat 系发型版下,可以使用 yum 来安装依赖。

$ sudo yum install libpcap libpcap-devel

或者从源码编译 libpcap。

# 安装依赖
$ sudo yum install gcc flex byacc bison
$ wget http://www.tcpdump.org/release/libpcap-1.8.1.tar.gz && tar xzf libpcap-1.8.1.tar.gz
$ cd libpcap-1.8.1
$ ./configure
$ sudo make install

cd 到 goreplay 的源码目录,执行命令。

# 纯静态编译
$ go build -ldflags '-extldflags "-static"'

如果编译成功,在当前目录会生成一个 goreplay 文件,试运行一下。

[vagrant@localhost goreplay]$ ./goreplay
Version:
2018/06/08 08:06:22 Required at least 1 input and 1 output

不依赖任何库。

[vagrant@localhost goreplay]$ ldd goreplay
    not a dynamic executable

一个合法的可执行文件。

[vagrant@localhost goreplay]$ file goreplay
goreplay: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=e334de401c00057ca56a33c0136dc5c86debee61, not stripped

如果遇到以下编译错误。

[vagrant@localhost goreplay]$ go build -ldflags '-extldflags "-static"'
# github.com/buger/goreplay
/home/vagrant/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status

需要安装 glibc 的静态库。

$ sudo yum install glibc-static.x86_64

如果不是通过 go get 来获取 goreplay,而是通过 git clone 下来的,那么会缺少一些第三方库的依赖,通过 go get 命令补充就好。

$ go get github.com/Shopify/sarama

3.2 input 和 output

input 和 output 是 goreplay 对数据流的抽象,在源码目录有很多 input_xxx.go 和 output_xxx.go,实现了 goreplay 的核心功能。

在启动的时候,会解析命令行参数中指定的 input 和 output,接着启动 emitter,从 input 中读数据,写到 output 中。

emitter.go 中核心代码如下:

for _, in := range Plugins.Inputs {
   
    go CopyMulty(in, Plugins.Outputs...)
}

多个 input 之间是并行的,但单个 input 到多个 output,是串行的。所有 input 都实现了 io.Reader 接口,output 都实现了 io.Writer 接口。所以阅读代码时,input 的入口是 Read() 方法,output 的入口是 Write() 方法。

3.3 UDP 抓包

抓包是核心功能,也算是一种 input 的类型。不过 goreplay 的实现中,实现上和 HTTP 协议绑定的很死。我参考 goreplay 的代码,实现了 goreplay-udp,用法上和 goreplay 保持一致。

目录
相关文章
|
中间件 Go 数据库
Go开发者必读:Gin框架的实战技巧与最佳实践
在当今快速发展的互联网时代,Web开发的需求日益增长。Go语言以其简洁、高效、并发性强的特点,成为了开发者们的首选。而在Go语言的众多Web框架中,Gin无疑是其中的佼佼者。本文将深入探讨Gin框架的特性、优势以及如何利用Gin构建高性能的Web应用。
|
Web App开发 域名解析 缓存
如何在 Ubuntu 20.04 上安装 Node.js 和 npm
本文我们主要为大家介绍在 Ubuntu 20.04 上安装 Node.js 和 npm 的三种不同的方式。
162250 7
如何在 Ubuntu 20.04 上安装 Node.js 和 npm
|
存储 域名解析 缓存
|
网络协议 Java 测试技术
性能工具之常见流量复制工具
我们把用户访问系统造成的数据传输定义为流量,那么在用户访问系统的过程中,我们可以把进入和流出的数据复制下来,进行保存,待后续使用,即离线模式,或者转发到一个新的服务器,立即使用,即在线模式。
664 2
性能工具之常见流量复制工具
|
5月前
|
人工智能 自然语言处理 JavaScript
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
Magnitude是一个基于视觉AI代理的开源端到端测试框架,通过自然语言构建测试用例,结合推理代理和视觉代理实现智能化的Web应用测试,支持本地运行和CI/CD集成。
726 15
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
|
消息中间件 网络协议 算法
流量回放工具之 goreplay 核心源码分析
【6月更文挑战第3天】流量回放工具之 goreplay 核心源码分析
312 3
|
9月前
|
人工智能 API 数据库
Browser Use:开源 AI 浏览器助手,自动完成网页交互任务,支持多标签页管理、视觉识别和内容提取等功能
Browser Use 是一款专为大语言模型设计的智能浏览器工具,支持多标签页管理、视觉识别、内容提取等功能,并能记录和重复执行特定动作,适用于多种应用场景。
2638 0
Browser Use:开源 AI 浏览器助手,自动完成网页交互任务,支持多标签页管理、视觉识别和内容提取等功能
|
Unix Linux Go
流量回放工具之 Goreplay 安装及初级使用
【6月更文挑战第2天】流量回放工具之 Goreplay 安装及初级使用
1183 3
|
11月前
|
运维 安全 新能源
中国石化的充电桩跑在了阿里云上!
中国石化的充电桩跑在了阿里云上!
227 1
|
中间件
流量回放工具之GoReplay output-http 源码分析
【6月更文挑战5天】流量回放工具之GoReplay output-http 源码分析
210 2

热门文章

最新文章