利用Go語言實現(xiàn)流量回放工具的示例代碼
前言
哈嘍,大家好,我是asong。
今天給大家推薦一款使用Go語言編寫的流量回放工具 -- goreplay;工作中你一定遇到過需要在服務(wù)器上抓包的場景,有了這個工具就可以助你一臂之力,goreplay的功能十分強大,支持流量的放大、縮小,并且集成了ElasticSearch,將流量存入ES進行實時分析;
廢話不多,我們接下來來看一看這個工具;
goreplay介紹與安裝
項目地址:https://github.com/buger/goreplay
goreplay是一個開源網(wǎng)絡(luò)監(jiān)控工具,可以實時記錄TCP/HTTP流量,支持把流量記錄到文件或者elasticSearch實時分析,也支持流量的放大、縮小,還支持頻率限制;goreplay不是代理,無需任何代碼入侵,只需要在服務(wù)相同的機器上運行goreplay守護程序,其會在后臺偵聽網(wǎng)絡(luò)接口上的流量,goreplay的設(shè)計遵循 Unix 設(shè)計哲學(xué):一切都是由管道組成的,各種輸入將數(shù)據(jù)復(fù)用為輸出;可以看一下官網(wǎng)畫的架構(gòu)圖:

goreplay的安裝也比較簡單,只需要在https://github.com/buger/goreplay/releases 下載對應(yīng)操作系統(tǒng)的二進制文件即可,我的電腦是mac的:

解壓縮后就是一個二進制文件gor,將其添加到您的環(huán)境變量中,方便我們后續(xù)的操作;
使用示例
實時流量轉(zhuǎn)發(fā)
首先我們要準備一個Web服務(wù),最簡單的就是用Gin 快速實現(xiàn)一個helloworld,替大家實現(xiàn)好了:https://github.com/asong2020/Golang_Dream/tree/master/code_demo/gin_demo;
import?(
?"flag"
?"github.com/gin-gonic/gin"
)
var?Port?string
func?init()??{
?flag.StringVar(&Port,?"port",?"8081",?"Input?Your?Port")
}
func?main()?{
?flag.Parse()
?r?:=?gin.Default()
?r.Use()
?r1?:=?r.Group("/api")
?{
??r1.GET("/ping",?func(c?*gin.Context)?{
???c.JSON(200,?gin.H{
????"message":?"pong",
???})
??})
?}
?r.Run("localhost:"?+?Port)
}
因為資源有限,這里我用一臺電腦起兩個進程來模擬流量轉(zhuǎn)發(fā),分別啟動兩個web服務(wù)分別監(jiān)控端口號8081、8082:
$?go?run?.?--port="8081" $?go?run?.?--port="8082"

服務(wù)弄好了,現(xiàn)在我們來開啟gor守護進程進行流量監(jiān)聽與轉(zhuǎn)發(fā),將8081端口的流量轉(zhuǎn)發(fā)到8082端口上:
$?sudo?gor?--input-raw?:8081?--output-http="http://127.0.0.1:8082"

現(xiàn)在我們請求8081端口:
$?curl?--location?--request?GET?'http://127.0.0.1:8081/api/ping'
可以看到8082端口同樣被請求了:

流量放大、縮小
goreplay支持將捕獲的流量存儲到文件中,實際工作中我們可以使用捕獲的流量做壓力測試,首先我們需要將捕獲的流量保存到本地文件,然后利用該文件進行流量回放;
還是上面的Web程序,我們將端口8081的流量保存到本地文件:
$?sudo?gor?--input-raw?:8081?--output-file?./requests.gor
我們對8081端口執(zhí)行了5次請求:

然后我們對8082端口進行流量縮小測試,縮小一倍:
gor?--input-file?"requests_0.gor"?--output-http="http://127.0.0.1:8082|50%"
調(diào)整百分比就是進行流量放大、縮小,這里我們縮小了一倍,可以看到只有2次請求到了8082端口;我們可以調(diào)整流量回放的速度,比如我們調(diào)整流量以10倍速度進行重播:
$?gor?--input-file?"requests_0.gor|1000%"?--output-http="http://127.0.0.1:8082|50%"?#?1000%就是放大10倍
流量寫入到ElastichSearch
goreplay可以將捕獲的流量導(dǎo)出到Es中,只需要執(zhí)行如下命令:
$?gor?--input-raw?:8000?--output-http?http://staging.cm??--output-http-elasticsearch?localhost:9200/gor
我們不需要提前創(chuàng)建索引結(jié)構(gòu),他將自動創(chuàng)建,具體結(jié)構(gòu)如下:
type?ESRequestResponse?struct?{
?ReqURL???????????????string?`json:"Req_URL"`
?ReqMethod????????????string?`json:"Req_Method"`
?ReqUserAgent?????????string?`json:"Req_User-Agent"`
?ReqAcceptLanguage????string?`json:"Req_Accept-Language,omitempty"`
?ReqAccept????????????string?`json:"Req_Accept,omitempty"`
?ReqAcceptEncoding????string?`json:"Req_Accept-Encoding,omitempty"`
?ReqIfModifiedSince???string?`json:"Req_If-Modified-Since,omitempty"`
?ReqConnection????????string?`json:"Req_Connection,omitempty"`
?ReqCookies???????????string?`json:"Req_Cookies,omitempty"`
?RespStatus???????????string?`json:"Resp_Status"`
?RespStatusCode???????string?`json:"Resp_Status-Code"`
?RespProto????????????string?`json:"Resp_Proto,omitempty"`
?RespContentLength????string?`json:"Resp_Content-Length,omitempty"`
?RespContentType??????string?`json:"Resp_Content-Type,omitempty"`
?RespTransferEncoding?string?`json:"Resp_Transfer-Encoding,omitempty"`
?RespContentEncoding??string?`json:"Resp_Content-Encoding,omitempty"`
?RespExpires??????????string?`json:"Resp_Expires,omitempty"`
?RespCacheControl?????string?`json:"Resp_Cache-Control,omitempty"`
?RespVary?????????????string?`json:"Resp_Vary,omitempty"`
?RespSetCookie????????string?`json:"Resp_Set-Cookie,omitempty"`
?Rtt??????????????????int64??`json:"RTT"`
?Timestamp????????????time.Time
}
goreplay提供了太多的功能,就不一一介紹了,可以通過執(zhí)行help命令查看其他高級用法,每個命令都提供了例子,入手很快;
$?gor?-h Gor?is?a?simple?http?traffic?replication?tool?written?in?Go.?Its?main?goal?is?to?replay?traffic?from?production?servers?to?staging?and?dev?environments. Project?page:?https://github.com/buger/gor Author:?<Leonid?Bugaev>?leonsbox@gmail.com Current?Version:?v1.3.0 ??-copy-buffer-size?value ?????Set?the?buffer?size?for?an?individual?request?(default?5MB) ??-cpuprofile?string ?????write?cpu?profile?to?file ??-exit-after?duration ?????exit?after?specified?duration ??-http-allow-header?value ?????A?regexp?to?match?a?specific?header?against.?Requests?with?non-matching?headers?will?be?dropped: ???????gor?--input-raw?:8080?--output-http?staging.com?--http-allow-header?api-version:^v1 ??-http-allow-method?value ?????Whitelist?of?HTTP?methods?to?replay.?Anything?else?will?be?dropped: ??????gor?--input-raw?:8080?--output-http?staging.com?--http-allow-method?GET?--http-allow-method?OPTIONS ??-http-allow-url?value ?????A?regexp?to?match?requests?against.?Filter?get?matched?against?full?url?with?domain.?Anything?else?will?be?dropped: ???????gor?--input-raw?:8080?--output-http?staging.com?--http-allow-url?^www. ??-http-basic-auth-filter?value ?????A?regexp?to?match?the?decoded?basic?auth?string?against.?Requests?with?non-matching?headers?will?be?dropped: ???????gor?--input-raw?:8080?--output-http?staging.com?--http-basic-auth-filter?"^customer[0-9].*" ??-http-disallow-header?value ?????A?regexp?to?match?a?specific?header?against.?Requests?with?matching?headers?will?be?dropped: ???????gor?--input-raw?:8080?--output-http?staging.com?--http-disallow-header?"User-Agent:?Replayed?by?Gor" ???????..........省略
goreplay基本實現(xiàn)原理
goreplay底層也是調(diào)用Libpcap,Libpcap即數(shù)據(jù)包捕獲函數(shù)庫,tcpdump也是基于這個庫實現(xiàn)的,Libpcap是C語言寫的,Go語言不能直接調(diào)用C語言,需要使用CGo,所以goreplay可以直接使用谷歌的包github.com/google/gopacket,提供了更方便的操作接口,基于goreplay封裝了input、output,在啟動的時候通過命令行參數(shù)解析指定的input、output,input讀取數(shù)據(jù)寫入到output中,默認是一個input復(fù)制多份,寫多個output,多個input之前是并行的,但是單個intput到多個output是串行的,所以input-file會有性能瓶頸,壓測的時候需要開多個進程同時跑來達到壓測需求;
goreplay的源碼有點多,就不在這里分析了,大家感興趣哪一部分可以從gor.go的main函數(shù)入手,看自己感興趣的部分就可以了;
總結(jié)
goreplay提供的玩法非常豐富,合理的改造可以做成回歸工具幫助我們確保服務(wù)的穩(wěn)定性,別放過這個自我展現(xiàn)的機會~。
以上就是利用Go語言實現(xiàn)流量回放工具的示例代碼的詳細內(nèi)容,更多關(guān)于Go語言流量回放工具的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Go語言中for循環(huán),break和continue的使用
這篇文章主要通過一些示例為大家介紹一下Go語言中for循環(huán)、break和continue的基本語法以及使用,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2022-06-06
golang對etcd存取和數(shù)值監(jiān)測的實現(xiàn)
這篇文章主要介紹了golang對etcd存取和數(shù)值監(jiān)測的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2019-09-09
Go語言數(shù)據(jù)結(jié)構(gòu)之插入排序示例詳解
這篇文章主要為大家介紹了Go語言數(shù)據(jù)結(jié)構(gòu)之插入排序示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08

