go replay流量重放的实现

 更新时间:2025年05月25日 10:58:05   作者:NPE~  
Goreplay 是用 Golang 写的一个 HTTP 实时流量复制工具,支持流量放大缩小、限流、文件记录及ES集成,本文主要介绍了go replay流量重放的实现,感兴趣的可以了解一下

一、介绍

  • Goreplay 是用 Golang 写的一个 HTTP 实时流量复制工具。功能更强大,支持流量的放大、缩小,频率限制,还支持把请求记录到文件,方便回放和分析,也支持和 ElasticSearch 集成,将流量存入 ES 进行实时分析。
  • GoReplay 不是代理,而是监听网络接口上的流量,不需要更改生产基础架构,而是在与服务相同的计算机上运行 GoReplay 守护程序。

Github地址:https://github.com/buger/goreplay

二、安装

进入官网下载对应操作系统版本,下载后解压即可使用

这里选择最新的v1.3.3为例:https://github.com/buger/goreplay/releases/download/1.3.3/gor_1.3.3_mac.tar.gz

下载完后可直接执行使用

在这里插入图片描述

三、参数讲解

1. 具体参数

# 查看帮助文档
./gor --help

常用参数:

–input-raw :用来捕捉http流量,需要指定ip地址和端口
–input-file :接收流量
–output-file:保存流量的文件
–input-tcp:将多个Goreplay实例获取的流量聚集到一个Goreplay实例
–output-stdout:终端输出
–output-tcp:将获取的流量转移至另外的Goreplay实例
–output-http:流量释放的对象server,需要指定IP地址和端口
–output-file:录制流量时指定的存储文件
–http-disallow-url :不允许正则匹配的URL
–http-allow-header :允许的Header头
–http-disallow-header:不允许的Header头
–http-allow-method:允许的请求方法,传入值为GET,POST,OPTIONS等
–input-file-loop:无限循环,而不是读完这个文件就停止了
–output-http-workers:并发请求数
–stats --out-http-stats 每5秒输出一次TPS数据(查看统计信息)
–split-output true: 按照轮训方式分割流量
–output-http-timeout 30s:http超时30秒时间设置,默认是5秒

2. 案例demo

  • 如果是性能测试,可以不考虑请求的顺序和速率,并且要求无限循环
# --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
  • 抓取80端口的HTTP请求,只抓取URL是/api/v1的,并输出到终端
./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'
  • 流量回放到多个站点(复制引流)
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
  • HTTP超时设置
gor --input-tcp replay.local:28020 --output-http http://staging.com --output-http-timeout 30s
  • 性能测试(表示放大2倍速度来回放)
gor --input-file "requests.gor|200%" --output-http "staging.com"
  • 回放速率不超过10QPS(绝对值)
gor --input-tcp :28020 --output-http "http://staging.com|10"
  • 回放不超过原流量的10%(百分比,这里是总流量的占比)
gor --input-raw :80 --output-tcp "replay.local:28020|10%"
  • 禁止的URL正则(除/api之外的请求)
gor --input-raw :8080 --output-http staging.com --http-disallow-url /api
  • 基于方法(表示只允许GET,OPTIONS的请求)
gor --input-raw :80 --output-http "http://staging.server" --http-allow-method GET --http-allow-method OPTIONS
  • 基于请求头
gor --input-raw :8080 --output-http staging.com --http-allow-header api-version:^1\.0\d
gor --input-raw :8080 --output-http staging.com --http-disallow-header "User-Agent: Replayed by Gor"
  • 重写请求
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
gor --input-raw :80 --output-http "http://staging.server" --http-header "User-Agent: Replayed by Gor" --http-header "Enable-Feature-X: true"
  • 导出到ES
./gor --input-raw :8000 --output-http http://staging.com  --output-http-elasticsearch localhost:9200/gor
  • 基于Header或URL参数值的一致限制
    如果您在Header或URL中存储了唯一的用户ID(例如API密钥),则可以仅针对该用户的一部分持续转发指定的流量百分比。基本公式如下:FNV32-1A_hashing(value) % 100 >= chance。例子:

当基于Header或参数进行限制时,仅支持基于百分比的限制

# Limit based on header value
sudo ./gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-header-limiter "X-API-KEY: 10%"

# Limit based on header value
sudo ./gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-param-limiter "api_key: 10%"

3. 注意点

  • 如果 HTTP 请求不符合规范,可能会抓不到包。遇到过 HTTP 请求头里面的 Content-Length 不等于实际的 Body 大小,goreplay 认为其请求未结束。
  • input-file 是单 goroutine 在跑,会有性能瓶颈。测试的时候,读取的 RPS 在 1.7w - 1.8w 左右,如果压测需求大于这个,需要开多个进程同时跑。
  • 多个 input 之间是并行的,但单个 input 到多个 output,是串行的。所有 input 都实现了 io.Reader 接口,output 都实现了 io.Writer 接口。所以阅读代码时,input 的入口是 Read() 方法,output 的入口是 Write() 方法。

四、具体使用

前置准备

本地编写http服务并启动,用于模拟线上服务器

勾选goland启动多实例选项,分别启动两个服务:localhost:8888、localhost:9999

选中main.go,鼠标右击配置

在这里插入图片描述

勾选允许多实例运行

在这里插入图片描述

先执行main.go运行实例1

在这里插入图片描述

修改暴露的端口,然后再执行main.go,运行实例2

在这里插入图片描述

最终效果

在这里插入图片描述

或者将port端口 暴露为参数,将main.go编译为可执行文件,然后分别运行两次。当然也可以直接编写两份一样的main函数,然后改下端口

用法一:本地录制流量保存到文件并回放到指定服务器

  • 启动goreplay(gor),执行命令,录制线上流量
#将端口 8888 流量保存到本地的文件
sudo ./gor --input-raw :8888 --output-file=requests.gor
  • 通过curl或postman等接口测试工具,访问服务
  • 暂停gor,观察录制的流量信息
1 f83d22b80000000169dd18f1 1736750112736464000 0
GET /getInfo HTTP/1.1
User-Agent: Apifox/1.0.0 (https://apifox.com)
Accept: */*
Host: localhost:8888
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
  • 回放流量,将流量回放到另一个服务器上
./gor --input-file requests_0.gor --output-http="http://localhost:9999"

用法二:将实时流量输出到控制台

  • 执行gor命令录制流量
# 将服务一的实时流量输出到控制台
sudo ./gor --input-raw :8888 --output-stdout
  • 通过curl或其他工具访问服务一,并观察控制台打印信息

用法三:将实时流量转发到服务二

  • 执行gor命令转发流量
# 将服务一的实时流量转发到服务二
sudo ./gor --input-raw "localhost:8888" --output-http="http://localhost:9999"
  • 通过curl或其他工具访问服务一,并观察服务二的请求信息

用法四:压测(流量放大或缩小)

goreplay支持将捕获到的生产实际请求流量减少或者放大重播以用于测试环境的压力测试.压力测试一般针对 Input 流量减少或者放大。

  • 执行gor命令进行流量缩放
# 将流量放大为200%,按照两倍速率去回放,比如:之前两个请求间的间隔为2s,我放大两倍后,请求间隔就变为了1s,相当于qps翻倍
# 如果“input-flie”是多个文件,可以用正则去匹配,如“request*.gor|200%”
# 除了input-file可以限流,--output-http也可以限流,详细文章后半部分
sudo ./gor --input-file "requests*.gor|1%" --output-http="http://localhost:9999"
  • 通过curl或其他工具访问服务一,并观察服务二的请求信息,观察请求是否有被放大或缩小

goreplay限流详细解释

goreplay支持将捕获到的生产实际请求流量减少或者放大重放以用于测试环境的压力测试,压力测试一般以对input的流量减少或者放大。例如:

# Replay from file on 2x speed
#将请求流量以2倍的速度放大重放;当然也支持10%,20%等缩小请求流量
gor --input-file "requests.gor|200%" --output-http "staging.com"

如果受限于测试环境的服务器的资源压力,只想重放一部分流量到测试环境中,而不需要所有的实际生产流量,那么就可以用限速功能。两种策略实现限流:

  • 随机丢弃请求流量
  • 基于Header或者URL丢弃一定的流量(百分比)

①随机丢弃请求流量:

input和output两端都支持限速,有两种限速算法,百分比或者绝对值

  • 百分比:input端支持缩小或者放大请求流量,基于指定的策略随机丢弃请求流量
  • 绝对值:如果单位时间(秒)内达到临界值,则丢弃剩余的请求流量,下一秒临界值还原

详细用法:

在output终端使用”|”运算符指定限速阈值,例如:

  • 使用绝对值限速(input端使用绝对值时,则对应QPS)
# staging.server will not get more than ten requests per second
#staging服务每秒只接收10个请求
gor --input-tcp :28020 --output-http "http://localhost:8082|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参数限速

如果header或者URL参数中有唯一值,例如(API key),则可以转发指定百分比的流量到后端,例如:

# 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 URL param value
gor --input-raw :80 --output-tcp "replay.local:28020|10%" --http-param-limiter "api_key: 10%"

五、代码地址

教程代码地址

Github:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-replay

参考文档:
https://juejin.cn/post/6999586008698208263
https://blog.csdn.net/qq_40093255/article/details/117227229

到此这篇关于go replay流量重放的实现的文章就介绍到这了,更多相关go replay流量重放内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • 解决goland新建项目文件名为红色的问题

    解决goland新建项目文件名为红色的问题

    这篇文章主要介绍了解决goland新建项目文件名为红色的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 详解Go程序添加远程调用tcpdump功能

    详解Go程序添加远程调用tcpdump功能

    这篇文章主要介绍了go程序添加远程调用tcpdump功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • 使用Golang调用摄像头并进行图像处理

    使用Golang调用摄像头并进行图像处理

    近年来,摄像头成为了我们生活中不可或缺的设备之一,从智能手机到安全监控系统,无处不在的摄像头给我们带来了便利和安全,在开发摄像头相关的应用程序时,选择一种高效和易用的编程语言是非常重要的,本文将介绍如何使用Golang调用摄像头并进行图像处理
    2023-11-11
  • 超详细Go语言中JSON处理技巧分享

    超详细Go语言中JSON处理技巧分享

    这篇文章主要为大家总结了go语言中对JSON数据结构和结构体之间相互转换问题及解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-06-06
  • golang并发执行的几种方式小结

    golang并发执行的几种方式小结

    本文主要介绍了golang并发执行的几种方式小结,主要包括了Channel,WaitGroup ,Context,使用这三种机制中的一种或者多种可以达到并发控制很好的效果,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • Golang操作MySql数据库的完整步骤记录

    Golang操作MySql数据库的完整步骤记录

    这篇文章主要给大家介绍了关于Golang操作MySql数据库的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 教你用go语言实现比特币交易功能(Transaction)

    教你用go语言实现比特币交易功能(Transaction)

    每一笔比特币交易都会创造输出,输出都会被区块链记录下来。给某个人发送比特币,实际上意味着创造新的 UTXO 并注册到那个人的地址,可以为他所用,今天通过本文给大家分享go语言实现比特币交易功能,一起看看吧
    2021-05-05
  • Golang HTTP请求Json响应解析方法以及解读失败的原因

    Golang HTTP请求Json响应解析方法以及解读失败的原因

    这篇文章主要介绍了Golang HTTP请求Json响应解析方法以及解读失败的原因,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • golang xorm日志写入文件中的操作

    golang xorm日志写入文件中的操作

    这篇文章主要介绍了golang xorm日志写入文件中的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Golang Slice和map的坑

    Golang Slice和map的坑

    Golang中的Slice和Map在内存空间上,有一些不同,本文主要介绍了Golang Slice和map的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-04-04

最新评论