go?replay流量重放的實現(xiàn)
一、介紹
- Goreplay 是用 Golang 寫的一個 HTTP 實時流量復制工具。功能更強大,支持流量的放大、縮小,頻率限制,還支持把請求記錄到文件,方便回放和分析,也支持和 ElasticSearch 集成,將流量存入 ES 進行實時分析。
- GoReplay 不是代理,而是監(jiān)聽網(wǎng)絡接口上的流量,不需要更改生產(chǎn)基礎(chǔ)架構(gòu),而是在與服務相同的計算機上運行 GoReplay 守護程序。
Github地址:https://github.com/buger/goreplay
二、安裝
進入官網(wǎng)下載對應操作系統(tǒng)版本,下載后解壓即可使用
這里選擇最新的v1.3.3為例:https://github.com/buger/goreplay/releases/download/1.3.3/gor_1.3.3_mac.tar.gz
下載完后可直接執(zhí)行使用
三、參數(shù)講解
1. 具體參數(shù)
# 查看幫助文檔 ./gor --help
常用參數(shù):
–input-raw :用來捕捉http流量,需要指定ip地址和端口 –input-file :接收流量 –output-file:保存流量的文件 –input-tcp:將多個Goreplay實例獲取的流量聚集到一個Goreplay實例 –output-stdout:終端輸出 –output-tcp:將獲取的流量轉(zhuǎn)移至另外的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:無限循環(huán),而不是讀完這個文件就停止了 –output-http-workers:并發(fā)請求數(shù) –stats --out-http-stats 每5秒輸出一次TPS數(shù)據(jù)(查看統(tǒng)計信息) –split-output true: 按照輪訓方式分割流量 –output-http-timeout 30s:http超時30秒時間設(shè)置,默認是5秒
2. 案例demo
- 如果是性能測試,可以不考慮請求的順序和速率,并且要求無限循環(huán)
# --input-file 從文件中獲取請求數(shù)據(jù),重放的時候 100x 倍速 # --input-file-loop 無限循環(huán),而不是讀完這個文件就停止 # --output-http 發(fā)送請求到 http://host2.com # --output-http-workers 并發(fā) 100 發(fā)請求 # --stats --output-http-stats 每 5 秒輸出一次 TPS 數(shù)據(jù) ./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超時設(shè)置
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
- 設(shè)置URL參數(shù)
gor --input-raw :8080 --output-http staging.com --http-set-param api_key=1
- 設(shè)置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參數(shù)值的一致限制
如果您在Header或URL中存儲了唯一的用戶ID(例如API密鑰),則可以僅針對該用戶的一部分持續(xù)轉(zhuǎn)發(fā)指定的流量百分比。基本公式如下:FNV32-1A_hashing(value) % 100 >= chance。例子:
當基于Header或參數(shù)進行限制時,僅支持基于百分比的限制
# 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 請求不符合規(guī)范,可能會抓不到包。遇到過 HTTP 請求頭里面的 Content-Length 不等于實際的 Body 大小,goreplay 認為其請求未結(jié)束。
- input-file 是單 goroutine 在跑,會有性能瓶頸。測試的時候,讀取的 RPS 在 1.7w - 1.8w 左右,如果壓測需求大于這個,需要開多個進程同時跑。
- 多個 input 之間是并行的,但單個 input 到多個 output,是串行的。所有 input 都實現(xiàn)了 io.Reader 接口,output 都實現(xiàn)了 io.Writer 接口。所以閱讀代碼時,input 的入口是 Read() 方法,output 的入口是 Write() 方法。
四、具體使用
前置準備
本地編寫http服務并啟動,用于模擬線上服務器
勾選goland啟動多實例選項,分別啟動兩個服務:localhost:8888、localhost:9999
選中main.go,鼠標右擊配置
勾選允許多實例運行
先執(zhí)行main.go運行實例1
修改暴露的端口,然后再執(zhí)行main.go,運行實例2
最終效果
或者將port端口 暴露為參數(shù),將main.go編譯為可執(zhí)行文件,然后分別運行兩次。當然也可以直接編寫兩份一樣的main函數(shù),然后改下端口
用法一:本地錄制流量保存到文件并回放到指定服務器
- 啟動goreplay(gor),執(zhí)行命令,錄制線上流量
#將端口 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"
用法二:將實時流量輸出到控制臺
- 執(zhí)行g(shù)or命令錄制流量
# 將服務一的實時流量輸出到控制臺 sudo ./gor --input-raw :8888 --output-stdout
- 通過curl或其他工具訪問服務一,并觀察控制臺打印信息
用法三:將實時流量轉(zhuǎn)發(fā)到服務二
- 執(zhí)行g(shù)or命令轉(zhuǎn)發(fā)流量
# 將服務一的實時流量轉(zhuǎn)發(fā)到服務二 sudo ./gor --input-raw "localhost:8888" --output-http="http://localhost:9999"
- 通過curl或其他工具訪問服務一,并觀察服務二的請求信息
用法四:壓測(流量放大或縮小)
goreplay支持將捕獲到的生產(chǎn)實際請求流量減少或者放大重播以用于測試環(huán)境的壓力測試.壓力測試一般針對 Input 流量減少或者放大。
- 執(zhí)行g(shù)or命令進行流量縮放
# 將流量放大為200%,按照兩倍速率去回放,比如:之前兩個請求間的間隔為2s,我放大兩倍后,請求間隔就變?yōu)榱?s,相當于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支持將捕獲到的生產(chǎn)實際請求流量減少或者放大重放以用于測試環(huán)境的壓力測試,壓力測試一般以對input的流量減少或者放大。例如:
# Replay from file on 2x speed #將請求流量以2倍的速度放大重放;當然也支持10%,20%等縮小請求流量 gor --input-file "requests.gor|200%" --output-http "staging.com"
如果受限于測試環(huán)境的服務器的資源壓力,只想重放一部分流量到測試環(huán)境中,而不需要所有的實際生產(chǎn)流量,那么就可以用限速功能。兩種策略實現(xiàn)限流:
- 隨機丟棄請求流量
- 基于Header或者URL丟棄一定的流量(百分比)
①隨機丟棄請求流量:
input和output兩端都支持限速,有兩種限速算法,百分比或者絕對值
- 百分比:input端支持縮小或者放大請求流量,基于指定的策略隨機丟棄請求流量
- 絕對值:如果單位時間(秒)內(nèi)達到臨界值,則丟棄剩余的請求流量,下一秒臨界值還原
詳細用法:
在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參數(shù)限速
如果header或者URL參數(shù)中有唯一值,例如(API key),則可以轉(zhuǎn)發(fā)指定百分比的流量到后端,例如:
# 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
到此這篇關(guān)于go replay流量重放的實現(xiàn)的文章就介紹到這了,更多相關(guān)go replay流量重放內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang并發(fā)執(zhí)行的幾種方式小結(jié)
本文主要介紹了golang并發(fā)執(zhí)行的幾種方式小結(jié),主要包括了Channel,WaitGroup ,Context,使用這三種機制中的一種或者多種可以達到并發(fā)控制很好的效果,具有一定的參考價值,感興趣的可以了解一下2023-08-08Golang操作MySql數(shù)據(jù)庫的完整步驟記錄
這篇文章主要給大家介紹了關(guān)于Golang操作MySql數(shù)據(jù)庫的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11教你用go語言實現(xiàn)比特幣交易功能(Transaction)
每一筆比特幣交易都會創(chuàng)造輸出,輸出都會被區(qū)塊鏈記錄下來。給某個人發(fā)送比特幣,實際上意味著創(chuàng)造新的 UTXO 并注冊到那個人的地址,可以為他所用,今天通過本文給大家分享go語言實現(xiàn)比特幣交易功能,一起看看吧2021-05-05Golang HTTP請求Json響應解析方法以及解讀失敗的原因
這篇文章主要介紹了Golang HTTP請求Json響應解析方法以及解讀失敗的原因,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03