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流量重放内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • golang实现webgis后端开发的步骤详解

    golang实现webgis后端开发的步骤详解

    这篇文章主要介绍如何用golang结合postgis数据库,使用gin、grom框架实现后端的MVC的接口搭建,文中有详细的流程步骤及代码示例,需要的朋友可以参考下
    2023-06-06
  • Golang数组的传递详解

    Golang数组的传递详解

    今天小编就为大家分享一篇关于Golang数组的传递详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 一文带你分析Go语言中的http请求过程

    一文带你分析Go语言中的http请求过程

    在go中开发后端,最基础的就是使用net/http包,本文将使用一个hello,world程序来进行debug,来探究在Go语言中http请求的过程,希望对大家有所帮助
    2026-02-02
  • go语言中decimal的用法详解

    go语言中decimal的用法详解

    本文主要介绍了go语言中decimal的用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Golang分布式应用之Redis示例详解

    Golang分布式应用之Redis示例详解

    这篇文章主要为大家介绍了Golang分布式应用之Redis示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Go语言列表List获取元素的4种方式

    Go语言列表List获取元素的4种方式

    Golang的列表元素的获取可以使用内置的 Front 函数获取头结点,使用 Back 函数获取尾结点,使用 Prev 获取前一个结点,使用 Next 获取下一个结点,本文就介绍了Go语言列表List获取元素的4种方式,感兴趣的可以了解一下
    2022-04-04
  • Golang标准库unsafe源码解读

    Golang标准库unsafe源码解读

    这篇文章主要为大家介绍了Golang标准库unsafe源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • golang内存对齐的概念及案例详解

    golang内存对齐的概念及案例详解

    为保证程序顺利高效的运行,编译器会把各种类型的数据安排到合适的地址,并占用合适的长度,这就是内存对齐。本文重点给大家介绍golang内存对齐的概念及案例详解,感兴趣的朋友一起看看吧
    2022-02-02
  • 基于go interface{}==nil 的几种坑及原理分析

    基于go interface{}==nil 的几种坑及原理分析

    这篇文章主要介绍了基于go interface{}==nil 的几种坑及原理分析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 使用Go goroutine实现并发的Clock服务

    使用Go goroutine实现并发的Clock服务

    这篇文章主要为大家详细介绍了如何使用Go goroutine实现并发的Clock服务,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-06-06

最新评论