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