GoReplay-流量录制与回放

GoReplay简介

GoReplay是一个开源的网络监控工具,它可以记录你的实时流量,并用于跟踪、负载测试、监控和详细分析。录制的流量可以在测试服务器上回放,并支持请求放大,用于性能测试。
github主页: https://github.com/buger/goreplay

GoReplay安装—linux

1
2
3
4
# 下载安装包
wget https://github.com/buger/goreplay/releases/download/v1.1.0/gor_1.1.0_x64.tar.gz
# 解压 得到二进制文件gor
tar -zxvf gor_1.1.0_x64.tar.gz

GoReplay安装—windows

文档地址: https://github.com/buger/goreplay/wiki/Running-on-Windows

安装nmap工具,进行流量的抓取,地址nmap或者technet,直接下载nmap,安装时勾选带有WinPcap的选项
win版二进制文件goreplay.zip

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1、如果没有web服务,可以在本地启动一个8000端口的文件服务器,并实时打印流量在控制台
./gor file-server :8000

# 2、获取8000端口的包,并打印在控制台
sudo ./gor --input-raw :8000 --output-stdout

# 获取8000端口的包,并保存在.gor文件中
sudo ./gor --input-raw :8080 --output-file=request.gor

# 转发:录制8000端口的包,并推送的测试系统
sudo ./gor --input-raw :8000 --output-http http://staging.env

# 转发至多个地址,默认每一条记录都发送到所有地址
sudo gor --input-tcp :28020 --output-http "http://staging.com" --output-http "http://dev.com"

# 转发至多个地址,轮询发送
sudo gor --input-raw :80 --output-http "http://staging.com" --output-http "http://dev.com" --split-output true

# 参数input-raw表示只记录请求信息,而参数--input-raw-track-response可以记录请求和响应

# 默认使用libpcap拦截流量,如果有问题,可以使用替代引擎raw_socket
sudo gor --input-raw :80 --input-raw-engine "raw_socket" --output-http "http://staging.com"

# 使用--input-raw-realip-header可以记录IP,header名称通常是X-Real_IP
sudo gor --input-raw :80 --input-raw-realip-header "X-Real-IP" ...

从文件保存和回放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 写入文件
gor --input-raw :80 --output-file requests.log

# 从文件读取
gor --input-file requests.gor --output-http "http://staging.com"

# 分文件存储,以时间格式保存,默认以块的形式追加,将不同的块到不同的文件
gor ... --output-file %Y%m%d.log
# append false
20140608_0.log
20140608_1.log
20140609_0.log
20140609_1.log
# 使用--output-file-append使文件不分块,都追加到同一个文件
gor ... --output-file %Y%m%d.log --output-file-append
# append true
20140608.log
20140609.log

# 块大小--output-file-size-limit限制块大小--output-file-queue-limit限制队列,如果只限制大小:
gor --input-raw :80 --output-file %Y-%m-%d.gz --output-file-size-limit 256m --output-file-queue-limit 0

# 文件名可以使用改的时间参数
%Y:年 %m:月 %d:日 %H:时 %M:分 %S:秒

# 读写SGZIP压缩文件,以.gz结尾
...--output-file log.gz

# 使用正则表达式读取多个文件,如:log2020*,根据时间戳给所有的文件请求进行排序

# 以多倍的速度进行回放,可以减缓或加快起速度,例:两倍速回放
gor --input-file "requests.gor|200%" --output-http "staging.com"

# 循环回放,当请求较少时,可以使用--input-file-loop循环回放,当回放完所有文件时,不会停止,而是从第一个重新开始

记录response

1
2
# 加入参数--input-raw-track-response即可
./gor --input-raw :8081 --input-raw-track-response --output-file uat-request%Y%m%d%H.log --output-file-append --http-disallow-url .*order.* .*aliPay.* .*wxPay.* .*refund.*

远程转发

1
2
3
4
# 转发至127.0.0.1:2020
./gor --input-raw :8081 --output-tcp 127.0.0.1:2020 --http-allow-url /admin
# 从远程接收
./gor --input-tcp :2020 --output-file admin-%Y%m%d%H.log --output-file-append

速度限制

输入和输出都支持速度限制,在上一个已经介绍了读取文件速度限制。

1
2
3
4
5
# 每秒钟不超过10条
gor --input-tcp :28020 --output-http "http://staging.com|10"

# 回放速度减缓10%
gor --input-raw :80 --output-tcp "replay.local:28020|10%"

可以根据请求头或地址参数设置回放速度限制,只按照这部分进行限速,只支持百分比

1
2
3
4
5
# 根据请求头限制速度
gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-header-limiter "X-API-KEY: 10%"

# 根据URL参数限制速度
gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-param-limiter "api_key: 10%"

请求过滤

如果只想抓取特定的请求,可以进行过滤,支持URL地址,HTTP header或者HTTP method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 正则匹配url,转发URL中包含/api的请求
gor --input-raw :8080 --output-http staging.com --http-allow-url /api
# 只转发不包含order、aliPay、wxPay、refund,正则表达式
./gor --input-raw :8081 --output-file uat-request%Y%m%d%H.log --output-file-append --http-disallow-url .*order.* .*aliPay.* .*wxPay.* .*refund.*

# 只转发不包含 /api 的请求
gor --input-raw :8080 --output-http staging.com --http-disallow-url /api

# 只转发 api 版本为 1.0x 的
gor --input-raw :8080 --output-http staging.com --http-allow-header api-version:^1\.0\d

# 只转发请求头 User-Agent 的值是 "Replayed by Gor"的
gor --input-raw :8080 --output-http staging.com --http-disallow-header "User-Agent: Replayed by Gor"

# 根据请求方法(GET、POSt……)进行过滤
gor --input-raw :80 --output-http "http://staging.server" \
--http-allow-method GET \
--http-allow-method OPTIONS

请求重写

gor支持对URL、URL参数和header的重写。可以用于将token进行重写,完成测试。

1
2
3
4
5
6
7
8
9
10
# 重写所有的`/v1/user/<user_id>/ping`为`/v2/user/<user_id>/ping`,可以使用正则表达式,用“:”进行分割
gor --input-raw :8080 --output-http staging.com --http-rewrite-url /v1/user/([^\\/]+)/ping:/v2/user/$1/ping

# 设置URL的参数,如果参数已经存在则覆盖
gor --input-raw :8080 --output-http staging.com --http-set-param api_key=1

# 设置自定义header,如果header已经存在则覆盖
gor --input-raw :80 --output-http "http://staging.server" \
--http-header "User-Agent: Replayed by Gor" \
--http-header "Enable-Feature-X: true"

分布式配置

一个服务有台服务器组成集群,gor对每天服务器进行请求转发,将集群的请求集中一起。

1
2
3
4
5
# 在每一个服务将流量转发至replay.local:28020
sudo gor --input-raw :80 --output-tcp replay.local:28020

# 回放服务
gor --input-tcp replay.local:28020 --output-http http://staging.com

如果要转发至多个服务中,可以使用–split-output,它可以轮询将入口流量回放到多个服务中

1
2
# 将流量轮询回放到两个服务
gor --input-raw :80 --split-output --output-tcp replay1.local:28020 --output-tcp replay2.local:28020

它还可以更智能的将同一个会话传递到同一个服务中,控制流量的从属。

1
2
3
4
5
# 读取多个文件、10倍速回放、30s循环、根据session分布式流量发送给多个服务
gor --input-file logs_from_multiple_machines.*|1000% --input-file-loop --exit-after 30s --recognize-tcp-sessions --split-output --output-tcp worker1.local --output-tcp worker2.local:27017 --output-tcp worker3.local:27017 ... --output-tcp workerN.local:27017

# worker
gor --input-tcp :27017 --ouput-http load_test.target

和Kafka配合使用

1
2
3
4
5
# 记录数据
gor --input-raw :8080 --output-kafka-host '192.168.0.1:9092,192.168.0.2:9092' --output-kafka-topic 'kafka-log'

# 读取数据
gor --input-kafka-host '192.168.0.1:9092,192.168.0.2:9092' --input-kafka-topic 'kafka-log' --output-stdout

通过–output-kafka-json-format和–input-kafka-json-format可以使用json格式进行读取和推送,但是会影响性能

参数解释

1
2
3
4
5
6
7
--input-raw -用户捕获HTTP流量,应指定IP(接口)以及端口
--input-file - 读取记录的文件,通过其他方式回放
--input-tcp - 将流量从多个转发gor转发到该实例
--output-http - 回放HTTP请求到指定站点,接受基本url
--output-file - 将HTTP请求流量到文件
--output-tcp - 将流量转发到另一个gor实例,使用--input-tcp接受
--output-stdout - 将THHP请求打印到控制台,在调试时使用

不使用root用户运行

1
2
3
4
5
6
7
8
9
# 1、将gor文件放到/usr/local/bin中
# 2、创建gor组和用户
groupadd gor
useradd -g gor gor
# 3、将gor文件所属给gor用户,设置权限
chgrp gor /usr/local/gor
chmod 0750 /usr/lcoa/gor
# 4、分割root用户特权
setcap "cap_net_raw,cap_net_admin+eip" /usr/local/bin/gor

至此,可以直接使用gor命令运行