您可以将请求保存到文件,并在稍后重播。重播时将保留请求之间的原始时间差异。如果您在两个请求之间应用[基于百分比的限制](速率限制)时间点,则会适当减少或增加:此方法可开启负载测试等可能性,请参见下文。
#写入文件
gor --input-raw:80 --output-file requests.log
#从文件读取
gor --input-file requests.gor --output-http “ http://staging.com ”
默认情况下,Gor以块的形式写入文件。这个可配置的使用--output-file-append
选项:刷新的块被附加到存在文件或不附加。默认值是false。默认情况下,--output-file
将每个块刷新到不同的路径。
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
如果您多次运行gor并找到现有文件,它将从最后一个已知索引继续。
块大小
您可以使用--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
在文件名中使用日期变量
例如,您可以告诉每小时创建一个新文件:--output-file /mnt/logs/requests-%Y-%m-%d-%H.log
它将为每个小时创建一个新文件:requests-2016-06-01-12.log,requests-2016-06-01-13.log,...
用作文件名称一部分的时间格式。创建文件时,以下字符将替换为实际值:
%Y
:包括世纪在内的年份(至少4位数字)
%m
:一年中的月份(01..12)
%d
:月中的某天(01..31)
%H
:一天中的小时,24小时制(00..23)
%M
:小时(00..59)
%S
:二分钟(00..60)
默认格式是%Y%m%d%H
,每小时创建一个文件。
GZIP压缩
要读取或写入GZIP压缩文件,请确保文件扩展名以“.gz”结尾: --output-file log.gz
从多个文件重播
--input-file
接受文件模式,例如:--input-file logs-2016-05-*
。GoReplay足够聪明,保持请求的原始顺序。它通过并行读取所有文件并通过时间戳在多个文件之间对请求进行排序来实现。它不会读取内存中的所有文件,而是根据需要在流媒体中读取它们。
缓冲的文件输出
Gor写入文件时拥有内存缓冲区,并持续刷新文件更改。如果缓冲区已满,则每隔1秒强制刷新一次,或者如果Gor关闭,则会发生冲突至文件。您可以使用--output-file-flush-interval
选项更改它。大多数情况下它不应该被触及。
文件格式
按原样存储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
来进行分析。您甚至可以手动编辑它们,但请确保您的文件编辑器不会更改行尾。
性能测试
目前,input-file
仅在使用基于百分比的限制器时才支持此功能。与默认限制器不同input-file
,它不会降低请求速度,而会减慢速度或加速请求发射。请注意限制器应用于输入:
# Replay from file on 2x speed
gor --input-file "requests.gor|200%" --output-http "staging.com"
使用--stats --output-http-stats
查看延迟统计。
循环播放文件以无限期重放
您可以循环同一组文件,因此当最后一个重放所有请求时,它不会停止,并且将从第一个重新开始。只有少量的请求可以进行广泛的性能测试。通过--input-file-loop
让它工作。
如果您只想转发部分传入流量,例如,不会超载您的测试环境,则速率限制可能很有用。有两种策略:根据标题或URL参数值丢弃随机请求或删除部分请求。
丢弃随机请求
每个输入和输出都支持随机速率限制。有两种限制算法:绝对或基于百分比。
绝对:如果在当前秒钟内达到了指定的请求限制 - 忽略其余,则在下一秒计数器重置时。
百分比:对于输入文件,它会减速或加速请求执行,其余的将使用随机生成器根据您指定的机会决定请求是否通过。
您可以使用“|”指定您想要的限制 服务器地址后的运算符,请参阅下面的示例。
限制重播使用绝对数量
# staging.server will not get more than ten requests per second
gor --input-tcp :28020 --output-http "http://staging.com|10"
使用基于百分比的限制器限制侦听器
# 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%"
基于Header或URL参数值的一致限制
如果您拥有存储在标头或URL中的唯一用户标识(如API密钥),则只能为该用户的一小部分转发指定的流量百分比。基本公式看起来像这样:FNV32-1A_hashing(value) % 100 >= chance
。例子:
# Limit based on header value
gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-header-limiter "X-API-KEY: 10%"
# Limit based on header value
gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-param-limiter "api_key: 10%"
当您只需要捕获特定部分的流量(如API请求)时,过滤非常有用。可以通过URL,HTTP标头或HTTP方法进行过滤。
允许URL正则表达式
# only forward requests being sent to the /api endpoint
gor --input-raw :8080 --output-http staging.com --http-allow-url /api
禁止URL正则表达式
# only forward requests NOT being sent to the /api... endpoint
gor --input-raw :8080 --output-http staging.com --http-disallow-url /api
基于标题的正则表达式筛选
# 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"
基于HTTP方法过滤
不匹配指定白名单的请求可以被过滤掉。例如,去除非零能力的请求:
gor --input-raw :80 --output-http "http://staging.server" \
--http-allow-method GET \
--http-allow-method OPTIONS
Gor支持重写URL,URL参数和标题,见下文。
如果测试环境没有与您的产品相同的数据,并且您希望在test
用户上下文中执行所有操作,则重写可能很有用:例如,将所有API令牌重写为某个测试值。其他可能的用例是使用自定义标题打开/关闭功能,或者如果在新环境中更改URL,则可以重写URL。
对于更复杂的逻辑,您可以使用中间件。
根据映射重写URL
--http-rewrite-url
预期“:”格式的值:“:”是一个稀释度。在<replace>
部分中,您可以使用捕获的正则表达式组值。这与replace
Javascript或gsub
Ruby中的方法类似。
# 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
设置网址参数
设置请求url参数,如果参数已经存在,它将被覆盖。
gor --input-raw :8080 --output-http staging.com --http-set-param api_key=1
设置标题
设置请求标题,如果标题已经存在,它将被覆盖。如果您需要确定由Gor生成的请求或在应用程序中启用功能标记的功能,可能会有用:
gor --input-raw :80 --output-http "http://staging.server" \
--http-header "User-Agent: Replayed by Gor" \
--http-header "Enable-Feature-X: true"
主机头
主机头获得特殊待遇。默认情况下,主机将被设置为--output-http中指定的值。如果您手动设置--http-header“Host:anonther.com”,则Gor不会覆盖主机值。
如果你的应用程序接受来自多个域的流量,并且你想保留原始头文件,具体--http-original-host
告诉Gor不要触摸Host头文件。
概观
GoReplay提供了NodeJS语言的框架,它隐藏了协议实现,并为编写中间件提供了原语,请参阅文档https://github.com/buger/goreplay/tree/master/middleware。但协议本身非常简单,您可以随意使用任何语言。
中间件是一个程序,它接受STDIN上的请求和响应负载,并在STDOUT处发出修改后的请求。您可以实现任何自定义逻辑,如剥离私人数据,高级重写,支持oAuth等。检查包含在我们的回购中的示例。
Original request +--------------+
+-------------+----------STDIN---------->+ |
| Gor input | | Middleware |
+-------------+----------STDIN---------->+ |
Original response (1) +------+---+---+
| ^
+-------------+ Modified request v |
| Gor output +<---------STDOUT-----------------+ |
+-----+-------+ |
| |
| Replayed response |
+------------------STDIN----------------->----+
(1):如果--input-raw-track-response
指定了选项,则原始响应只会发送给中间件。
中间件可以用任何语言编写,请参阅examples/middleware
文件夹中的示例。中间件程序应该接受与Gor的所有通信都是异步的,不能保证原始请求和响应消息会一个接一个地出现。如果逻辑取决于原始响应或重播响应,则应用程序应该处理状态,请参阅examples/middleware/token_modifier.go
示例。
简单的bash echo中间件(返回相同的请求)将如下所示:
while read line; do
echo $line
end
--middleware
通过指定可执行文件的路径,可以使用选项启用中间件:
gor --input-raw :80 --middleware "/opt/middleware_executable" --output-http "http://staging.server"
有时候使用单独的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
加密
之间的通信量--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"`
什么操作系统支持?
Gor会在libpcap工作的地方运行,并且它可以在大多数平台上运行。但是,目前,我们在Linux和Mac上进行测试。查看更多关于汇编。
为什么--input-raw
需要sudo或root访问?
侦听器通过嗅探来自特定端口的流量来工作。它只能通过使用sudo或root访问来访问。但可以以非root用户身份运行。
你如何处理用户会话以正确重放流量?
您可以重写会话相关的头文件/ params以匹配您的分段环境。如果您需要自定义逻辑(例如基于随机令牌的身份验证),请参阅此讨论:https://github.com/buger/gor/issues/154
我可以使用Gor拦截SSL流量吗?
基本思想是SSL是为了保护自己免受交通拦截。有2个选项:
- 将SSL处理移至代理,如Nginx或Amazon ELB。让Gor听听上游。
- 使用
--input-http
这样你可以直接从您的应用程序复制请求有效载荷到Gor,但它会需要您的应用程序修改。
更多可以在这里找到:https://github.com/buger/gor/issues/85
使用output-http时HTTP请求的大小是否有限制?
由于Gor无法保证截取所有数据包,因此对于大于200kb的有效载荷,有可能丢失一些数据包和腐败主体。将其视为一项功能,并有机会测试处理破碎的物体:)保证交付的唯一方法就是使用--input-http
,但您会错过一些功能。
我得到'太多打开文件'的错误
典型的Linux shell在1024下有一个小的打开文件软限制。在开始gor重放过程之前,你可以很容易地提出这个问题:
ulimit -n 64000
关于ulimit的更多信息:http : //www.thecodingmachine.com/solving-the-too-many-open-files-exception-in-red5-or-any-other-application/
我的负载平衡目标的CPU平均值高于源
如果您正在将来自多个侦听器的流量重放到负载平衡目标并使用粘性会话,则可能会发现目标服务器的CPU负载高于侦听器服务器。这可能是因为原始负载均衡器的粘性会话cookie未被目标负载均衡器所尊敬,从而导致请求通常会碰到同一个目标服务器,从而降低了后端的不同服务器的负载,从而降低了通过负载平衡获得的一些缓存收益。尝试针对一个重播目标运行一个侦听器,并查看CPU利用率比较是否更准确。
另请参阅故障排除。
不要忘记用您的域名或IP替换“localhost”。
在配置安全输入时,--output-tcp-secure
为GoReplay客户端启用标志,并连接到它。
GoReplay PRO支持精确记录和重播tcp会话,并且当--recognize-tcp-sessions
选项通过时,而不是循环,它将使用更智能的算法,确保同一会话将被发送到同一个重播实例。
如果您计划进行大型负载测试,则可以考虑使用单独的主控实例来控制实际重放流量的Gor从站。例如:
# This command will read multiple log files, replay them on 10x speed and loop them if needed for 30 seconds, and will distributed traffic (tcp session aware) among multiple workers
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