goreplay学习笔记

一、简介

1.内容来源

学习笔记,主要基于HTTP引流神器Goreplay详解【精译】

2. goreplay是什么

goreplay是google出的一款用于引流开源软件,它可以将A环境的流量引到B环境。常用的场景是将线上的请求引流到灰度测试环境。

goreplay分为免费版与专业版goerplay pro,专业版需要付费。

3. 为什么需要goreplay

当系统上线或有更新时,常见的测试手段是靠测试用例、模拟用户场景等进行检验和测试,但这些无法完整的覆盖生产环境下的场景。所以需要使用工具将线上的正常请求引流到灰度测试环境,用于对新上线的系统或更新进行测试。

4. goreplay架构与流程

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

5. 问题

goreplay无法完全的重播所有的流量请求。

goreplay的工作原理是收集网络接口上的原始TCP包。数据包可以是随机的顺序到达,goreplay基于数据包重新构建TCP流,并按照正确的顺序从TCP数据包中提取数据。

HTTP这样的协议重构起来可能非常复杂,因为消息可以被分成多个包,而且在请求和响应TCP流之间的关系不是那么明显的情况下,比如处理100个继续消息。如果该流中的一个包由于某种原因无法被跟踪,则消息将被损坏或GoReplay将无法在请求和响应之间建立关联。

5.1 官方描述

By its nature, GoReplay works by collecting raw TCP packets on network interface. The packets can arrive in random order, and role of GoReplay, in this case, is to re-construct TCP flow and extract data from TCP packets in the right order. Protocols like HTTP can be quite complex to re-construct since messages can divided to multiple packets, and there are cases like handling 100 continue messages, when relations between request and response TCP flows are not that obvious. If one of the packets in this flow for some reason will not be tracked, message will be either corrupted or GoReplay will not be able to build association between request and response.

Traffic interception techniques, like GoReplay use, do not provide 100% guarantee that all packets will be processed. Interception itself happens on OS kernel level, and GoReplay use libpcap library to talk with this APIs. In general, OS maintain some internal buffer where it temporary holds the packets, until they will be processed by the application, which does intercepting, e.g. GoReplay. If buffer overfills, packets gets discarded. So if buffer gets overfilled faster then application process packets, you may see a package drop.You may control buffer usage using 2 variables: Snap length – number of bytes used to read the packet, and Buffer size itself. The less is Snap length, the more packets will fit into the buffer.

二、goreplay安装

1. 二进制安装

参考官方文档:https://github.com/buger/goreplay/wiki/Compilation

2. 下载编译包

wget -S https://github.com/buger/goreplay/releases/download/v1.3.2/gor_1.3.2_x64.tar.gz 
tar -zxvf gor_1.3.2_x64.tar.gz; 
chmod +x gor;

三、使用方式

1. 基础概念

gor分为可用输入和可用输出。可用输入主要用来捕获流量,可用输出主要用来将捕获的流量按照规则重放。

1.1 gor可用输入

–input-raw – 用于捕获HTTP流量,您应该指定IP地址或接口和应用程序端口。有关捕获和重放流量的更多信息。

–input-file- 接受之前使用的文件–output-file。更多关于保存和从文件重播

–input-tcp – 如果您决定将来自多个转发器Gor实例的流量转发给它,则由Gor聚合实例使用。阅读关于使用Aggregator-forwarder设置

1.2 gor可用输出

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

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

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

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

gor的运行需要用户具有sudo权限。

2. 捕获重放流量

2.1 捕获流量并重播

捕获本机80端口的http流量,并在test.com上面重播

sudo gor --input-raw:80 --output-http http://test.com

2.2 gor可以将流量重播到多个地址

捕获本机28020端口的http流量,并在test1.com和test2上面重播

gor --input-tcp :28020 --output-http "http://test1.com" --output-http "http://test2.com"

2.3 将流量均分重播到多个地址

gor将流量重播到多个端口,默认是将捕获到的流量发送到所有的重播地址,如果希望多个地址均分捕获的流量,可以使用–spli-output参数。

gor --input-raw :80 --output-http "http://test1.com" --output-http "http://test2.com" --split-output true

2.4 拦截回复

gor默认情况下不拦截回复,可以使用–input-raw-track-response参数回复拦截。

2.5 替换默认引擎

gor默认使用libpcap拦截流量,还可以使用raw_socket引擎。

sudo gor --input-raw :80 --input-raw-engine "raw_socket" --output-http "http://staging.com"

2.6 透传原始ip

gor可以透传原始的请求ip。可以使用–input-raw-realip-header指定标题名称,一般使用”X-Real-IP”,也可以使用任意的名字。

gor --input-raw :80 --input-raw-realip-header "X-Real-IP" ...

3. 重播HTTP流量

3.1 HTTP输出工作者

默认情况下,Gor创建一个动态工作池:它从10开始,并在HTTP输出队列长度大于10时创建更多的HTTP输出工作者。创建的工人数量(N)等于该工作时间的队列长度检查并发现其长度大于10。每次将消息写入HTTP输出队列时都检查队列长度。在产生N名工人的请求得到满足之前,不会再有工人产卵。如果动态工作人员当时不能处理消息,它将睡眠100毫秒。如果动态工作人员无法处理消息2秒钟,则会死亡。您可以使用–output-http-workers=20选项指定固定数量的工人 。

3.2 http重定向

默认情况下,Gor会忽略所有重定向,因为它们是由使用您的应用的客户端处理的,但在重播环境引入新重定向的情况下,您可以像这样启用它们:

gor --input-tcp replay.local:28020 --output-http http://staging.com --output-http-redirects 2

给出的示例将跟随每个请求最多2个重定向。

3.3 http超时

默认情况下,http请求和响应的超时时间为5秒,可以使用–output-http-timeout参数自定义超时时间。

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

3.4 响应缓冲区

默认情况下,为了减少内存消耗,内部HTTP客户端将获取响应主体的最大200kb(在使用中间件时使用),通过使用–output-http-response-buffer选项可增加限制(接受字节数)。

3.5 身份验证

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

注意:这将覆盖原始请求中的任何授权标头。

3.6 多域名支持

–http-original-host可以使用’–http-original-host’参数保留原始的Host头

4.保存并从文件重放

goreplay可以将捕获的流量保存到文件,并可以从文件中重播。

4.1 写入文件

gor --input-raw:80 --output-file requests.log

4.2 从文件读取

gor --input-file requests.gor --output-http "http://test.com"

4.3 文件保存格式

4.3.1 文件内容格式

按原样存储HTTP请求,纯文本:标题和正文。请求按\n???\n行分隔(使用此类序列以获得唯一性和乐趣)。在每个请求进行单线行包含有效负载类型(1 – 请求,2 – 响应,3 – 重播响应)的元信息时,请求发出时,唯一请求标识(请求和响应具有相同)和时间戳。2个请求的示例:

1 d7123dasd913jfd21312dasdhas31 127345969\n 
GET / HTTP/1.1\r\n
\r\n 
\n 
??? 
\n 
POST /upload HTTP/1.1\r\n 
Content-Length: 7\r\n 
Host: www.w3.org\r\n 
\r\n 
a=1&b=2 

请注意,技术上\ r和\ n符号是不可见的,并指示新行。为了展示它在字节级别的外观,我在示例中使它们可见。

使其文本友好可以编写简单的解析器并使用控制台工具grep来进行分析。您甚至可以手动编辑它们,但请确保您的文件编辑器不会更改行尾。


4.3.2 文件保存形式

默认,gor以块的形式写入文件。可以使用–output-file-append取消使用块的方式写入。

gor ... --output-file%Y%m%d.log 
# append false 
20140608_0.log 
20140608_1.log 
20140609_0.log 
20140609_1.log
gor ... --output-file%Y%m%d.log --output-file-append 
# append true 
20140608.log
20140609.log

4.4 块大小

可以使用–output-file-size-limit和–output-file-queue-limit选项设置块限制。块队列的长度和每个块的大小。默认值分别是256和32mb。可以使用后缀“k”(KB),“m”(MB)和“g”(GB)output-file-size-limit。如果你只想要大小限制,你可以设置–output-file-queue-limit为0,反之亦然。

gor --input-raw:80 --output-file%Y-%m-%d.gz --output-file-size-limit 256m --output-file-queue-limit 0

4.5 文件保存名中添加日期

用作文件名称一部分的时间格式。创建文件时,以下字符将替换为实际值:

  • %Y:包括世纪在内的年份(至少4位数字)
  • %m:一年中的月份(01..12)
  • %d:月中的某天(01..31)
  • %H:一天中的小时,24小时制(00..23)
  • %M:小时(00..59)
  • %S:二分钟(00..60)

4.6 压缩

要读取或写入GZIP压缩文件,请确保文件扩展名以“.gz”结尾: –output-file log.gz

4.7 从多个文件重播

–input-file接受文件模式,例如:–input-file logs-2016-05-*。GoReplay足够聪明,保持请求的原始顺序。它通过并行读取所有文件并通过时间戳在多个文件之间对请求进行排序来实现。它不会读取内存中的所有文件,而是根据需要在流媒体中读取它们。

4.8 缓存刷新

Gor写入文件时拥有内存缓冲区,并持续刷新文件更改。如果缓冲区已满,则每隔1秒强制刷新一次,或者如果Gor关闭,则会发生冲突至文件。您可以使用–output-file-flush-interval选项更改它。大多数情况下它不应该被触及。

4.9 性能测试

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

# Replay from file on 2x speed gor --input-file "requests.gor|200%" --output-http "test.com"

4.9.1 无限重播

可以通过–input-file-loop实现无限重播。

5. 限速

gor可以只转发部分流量。有两种策略:根据标题或url参数值丢弃随机请求或删除部分请求。

5.1 丢弃随机请求

每个输入和输出都支持随机速率限制。有两种限制算法:绝对或基于百分比。

绝对:如果在当前秒钟内达到了指定的请求限制 – 忽略其余,则在下一秒计数器重置时。

百分比:对于输入文件,它会减速或加速请求执行,其余的将使用随机生成器根据您指定的机会决定请求是否通过。

您可以使用“|”指定您想要的限制 服务器地址后的运算符,请参阅下面的示例。

5.1.1 限制重播使用绝对数量

# staging.server will not get more than ten requests per second gor --input-tcp :28020 --output-http "http://staging.com|10"

5.1.2 使用基于百分比的限制器限制侦听器

# replay server will not get more than 10% of requests # useful for high-load environments gor --input-raw :80 --output-tcp "replay.local:28020|10%" 

5.2 基于Header或URL参数值的一致限制

如果您拥有存储在标头或URL中的唯一用户标识(如API密钥),则只能为该用户的一小部分转发指定的流量百分比。基本公式看起来像这样:FNV32-1A_hashing(value) % 100 >= chance。例子:

gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-header-limiter "X-API-KEY: 10%" gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-param-limiter "api_key: 10%"

6. 请求过滤

gor支持基于url、HTTP头、HTTP方法进行过滤。

6.1 允许URL正则表达式

# only forward requests being sent to the /api endpoint gor --input-raw :8080 --output-http staging.com --http-allow-url /api

6.2 禁止URL正则表达式

# only forward requests NOT being sent to the /api... endpoint gor --input-raw :8080 --output-http staging.com --http-disallow-url /api

6.3 基于HTTP头的正则表达式筛选

# only forward requests with an api version of 1.0x gor --input-raw :8080 --output-http staging.com --http-allow-header api-version:^1\.0\d # only forward requests NOT containing User-Agent header value "Replayed by Gor" gor --input-raw :8080 --output-http staging.com --http-disallow-header "User-Agent: Replayed by Gor"

6.4 基于HTTP方法过滤

不匹配指定白名单的请求可以被过滤掉。例如,去除非零能力的请求:

gor --input-raw :80 --output-http "http://staging.server" \ --http-allow-method GET \ --http-allow-method OPTIONS


7. 请求重写

gor支持重写URL、URL参数、HTTP头

7.1 根据映射重写URL

–http-rewrite-url预期“:”格式的值:“:”是一个稀释度。在<replace>部分中,您可以使用捕获的正则表达式组值。这与replaceJavascript或gsubRuby中的方法类似。

# Rewrites all `/v1/user/<user_id>/ping` requests to `/v2/user/<user_id>/ping` gor --input-raw :8080 --output-http staging.com --http-rewrite-url /v1/user/([^\\/]+)/ping:/v2/user/$1/ping

7.2 设置网址参数

设置请求url参数,如果参数已经存在,它将被覆盖。

gor --input-raw :8080 --output-http staging.com --http-set-param api_key=1

7.4 设置HTTP头

设置请求HTTP头,如果HTTP头已经存在,它将被覆盖。如果您需要确定由Gor生成的请求或在应用程序中启用功能标记的功能,可能会有用:

gor --input-raw :80 --output-http "http://staging.server" \ --http-header "User-Agent: Replayed by Gor" \ --http-header "Enable-Feature-X: true"

7.5 主机头

主机头获得特殊待遇。默认情况下,主机将被设置为–output-http中指定的值。如果您手动设置–http-header“Host:anonther.com”,则Gor不会覆盖主机值。如果你的应用程序接受来自多个域的流量,并且你想保留原始头文件,具体–http-original-host告诉Gor不要触摸Host头文件。

8.中间件

gor支持中间件,具体可参考文档:https://github.com/buger/goreplay/tree/master/middleware

9.分布式配置

9.1 配置

有时候使用单独的Gor实例重播流量并执行负载测试等事情是有意义的,因此您的生产计算机不会花费宝贵的资源。可以在您的Web计算机上配置Gor,将流量转发到在单独的服务器上运行的Gor聚合器实例。

#在您想要捕获流量的服务器上运行。你可以在每台`web`机器上运行它。
sudo gor --input-raw:80 --output-tcp replay.local:28020 


#重播服务器(replay.local)。 
gor --input-tcp replay.local:28020 --output-http http://staging.com 

如果您有多个重播机器,您可以使用–split-output选项将流量分割为多个:使用循环算法将所有传入流量均分为所有输出。

gor --input-raw :80 --split-output --output-tcp replay1.local:28020 --output-tcp replay2.local:28020

9.2 加密

之间的通信量–input-tcp和–output-tcp可使用TLS协议进行加密。要使其生效,您需要生成SSL证书,指定路径以及用于生成证书的密钥,并启用安全模式。

证书和密钥应该是PEM编码的。例如:–input-tcp :28020 –input-tcp-secure –input-tcp-certificate ./cert.pem –input-certificate ./key.pem。您可以使用以下命令生成自签名证书和密钥:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -subj "/CN=localhost"`

四、常见问题

FAQ:https://github.com/buger/goreplay/wiki/FAQ

故障排除:https://github.com/buger/goreplay/wiki/Troubleshooting

五、goreplay资料

文档:https://github.com/buger/goreplay/wiki

入门:https://github.com/buger/goreplay/wiki/Getting-Started

中间件:https://github.com/buger/goreplay/tree/master/middleware

goreplay pro:https://goreplay.org/pro.html

HTTP引流神器Goreplay详解【精译:https://www.cnblogs.com/sunsky303/p/9072871.html

故障排除:https://github.com/buger/goreplay/wiki/Troubleshooting

Previous Post

docker修改网桥默认ip网段

Next Post

iptables学习笔记

Related Posts