文章首發公衆號「碼農吳先生」, 歡迎關注,及時獲取更多技術幹活~python
「流量複製」經常應用在準生產環境的測試中,將線上的流量複製到一個準生產環境服務中,測試新功能和服務的承壓能力。流量複製能夠徹底模擬線上的流量,對複雜的業務場景進行真實的服務測試,又不會對生產服務產生任何反作用。nginx
對於複雜的流量複製應用場景和需求,徹底能夠立項開發一套完整的複製架構,可參考字節團隊自研的 ByteCopy 項目。而對於一些簡單的需求,開源的工具基本能夠搞定。開源的流量複製工具備不少,經常使用的有 goreplay、tcpreplay、tcpcopy 等。git
本文主要來探討下 tcpcopy 和 goreplay 的方案實現,廢話很少說開整。github
tcpcopy 由網易技術部王斌等開發,並於 2011 年 9 月開源的。tcpcopy 最新架構以下(來自做者王斌博客:blog.csdn.net/wangbin579/…golang
tcpcopy 主要有兩個組件構成 tcpcopy client 和 intercept 。client 端負責複製流量和轉發,intercept 負責對迴應流量的攔截和 tcpcopy 的連接處理。ubuntu
實例環境以下,下面來闡述下整個架構的搭建過程:bash
各組件可直接從 github 下載源碼包,編譯安裝:服務器
# 起壓機部署 tcpcopy client 192.168.33.11
wget https://github.com/session-replay-tools/tcpcopy/archive/1.0.0.tar.gz
tar xvf 1.0.0.tar.gz
cd tcpcopy-1.0.0
./configure --prefix=/opt/tcpcopy
make
make install
# 輔助機部署 intercept 192.168.33.12 , 截獲包須要依賴 libpcap 抓包函數庫
yum -y install libpcap-devel
# ubuntu
# apt install -y libpcap-dev
https://github.com/session-replay-tools/intercept/archive/1.0.0.tar.gz
tar xvf 1.0.0.tar.gz
cd intercept-1.0.0
./configure --prefix=/opt/tcpcopy/
make
make install
複製代碼
安裝完以後,先啓動 intercept,運行以下命令:markdown
/opt/tcpcopy/sbin/intercept -i enp0s8 -F 'tcp and src port 8000' -d
# -i,指定網卡 enp0s8
# -F,過濾,語法和pcap抓包工具一直,如tcpdump
# -d,以domain的形式啓動。
# 其餘參數可 -h 查看。
複製代碼
啓動 intercept 以後,再啓動 tcpcopy client 。tcpcopy 啓動依賴 intercept ,啓動時確保 intercept 啓動成功。網絡
/opt/tcpcopy/sbin/tcpcopy -x 8000-192.168.33.13:8000 -s 192.168.33.12 -c 192.168.1.x -n 2 -d
# -x,複製本地8000端口的流量,轉發到192.168.33.13機器的8000端口
# -s,輔助服務器intercept 地址
# -c,修改轉發包的原地址爲該地址段的地址,這裏也能夠是明確的ip。這個ip端用來假裝數據包,方便intercept作路由劫持。
# -n,流量倍數
# -d,以domain的形式運行
複製代碼
在測試服務器添加攔截路由,以下:
# 測試機 192.168.33.13
route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.33.12
複製代碼
該路由至關於把到 192.168.1.0 網段的包都走網關 192.168.33.12,對測試服務器的回包作僞地址攔截。
這即是 tcpcopy 的整個架構部署了。
下面咱們抓包看看這個過程當中包是如何流動的。
我在 tcpcopy client 機器 192.168.33.11 和測試機器 192.168.33.13 使用 python -m SimpleHTTPServer
分別起了一個 8000 端口的服務用來測試,從我本機 192.168.33.1 發送請求,在三臺機器上抓包。
tcpcopy client 機器 192.168.33.11 包信息以下:
紅色標註塊爲我本機(192.168.33.1)和 tcpcopy client 機器(192.168.33.11)的正常請求交換,從三次握手,到 http 請求,到最後的斷鏈。
藍色標註塊則爲 tcpcopy 複製的流量,能夠看到爲了讓 intercepter 攔截回包流量,tcpcopy 已將包源 ip 地址替換爲咱們指定的僞網段(192.168.1.0)的地址,這樣在回包時,就會根據測試服務器上的路由將回包指向輔助服務器 intercept,避免對生產流量形成影響。這也是爲何複製流量三次握手和 http 都沒有回包的緣由。
看測試服務器 192.168.33.13 的包:
測試服務器的包和正常流量包同樣,三次握手到 http 請求,最後斷連。這裏和測試服務器 192.168.33.13 交互的源地址 ip 已經被 tcpcopy 替換爲僞 ip 192.168.1.1 。
看 intercept 192.168.33.12 的包:
能夠看到輔助服務器攔截下來的請求,標註塊 1 爲複製流量三次握手時的回包,標註塊 2 爲 http 請求的回包,這即是 intercept 的攔截功能。能夠看到在標註塊 一、2 以後,輔助服務器(192.168.33.12)和 tcpcopy 服務器(192.168.33.11)進行了數據交換,這部分即是 intercept 的 tcp 處理功能,它把有用的信息返回給 tcpcopy 以便能使 tcpcopy 和測試機的 tcp 連接完成。
根據上邊抓包,咱們獲得了和架構圖同樣的包流動過程,總結以下:
根據官方文檔,咱們還須要注意幾個問題:
ip_forward
Goreplay 是另外一個比較經常使用的流量複製開源工具。與 tcpcopy 相比它的架構更簡單,只有一個 gor 組件,以下:
只須要在生產服務器上啓動一個 gor 進程,它負責全部的工做包括監聽、過濾和轉發。 它的設計遵循 Unix 設計哲學:一切都是由管道組成的,各類輸入將數據複用爲輸出。
輸入輸出一般被成爲插件,常見的有下面幾種。
可用輸入:
可用輸出:
你能夠對數據進行限速、過濾、從新,還能夠重用中間件實現一些自定義邏輯處理,如私有數據的過濾、認證等個性需求。
其餘經常使用參數:
本文不對中間件作過多描述,僅討論經常使用功能,對中間件有需求的可參考中間件文檔。
Goreplay 是使用 golang 開發的,咱們能夠直接使用編譯好的對應各系統的二進制文件,也能夠本身編譯,咱們這裏直接使用二進制文件。
wget https://github.com/buger/goreplay/releases/download/v1.3.0_RC1/gor_1.3_RC1_x64.tar.gz
tar zxvf gor_1.3_RC1_x64.tar.gz
# 解壓出二進制文件 gor
gor
複製代碼
接下來,直接啓動 gor 便可複製流量和轉發。
sudo ./gor --input-raw :8000 --output-http="http://192.168.33.13:8001"
複製代碼
複製本地 8000 端口的流量到 http 遠端服務http://192.168.33.13:8001
。(複製同端口的流量時,流量會重複。這是 gor 的一個 bug,截止目前 1.3 版本仍可復現,可見issue292)
goreplay 的流量轉發,並非直接 tcp 包的轉發,而是從新組織 http 協議級別的請求,發送到測試服務器。因此它是新的 gor 線程和測試服務器的交互,和監聽線程無關,因此無需對流量進行攔截。
下面咱們來看下 gor 複製的流量包的流向過程:
紅色標註塊爲正常流量,藍色標註塊爲複製的流量。
看到此處,你可能會有疑問,爲何 gor 不用攔截流量?
你們仔細看 tcpcopy 和 gor 複製流量的端口,在生產機和測試機創建鏈接時,tcpcopy 雖然修改了 tcp 包的源 ip,但端口仍是用的請求客戶端的端口,是 tcp 數據鏈路層級別的流量複製。而 gor 這裏嚴格來講並非複製,而是從新構建了 http 請求。使用新端口來和測試機建連,相對的測試機在回包時,即便包是回到了生產機,但因爲是和客戶端不一樣的端口,也不會對生產流量形成影響。
到此,咱們對流量複製有了些基本的概念和應用了,也對 tcpcopy 和 goreplay 兩款開源工具備了必定的認知。兩款開源工具各有優缺點,咱們來一塊總結下。
簡單 http 複製 goreplay 徹底能夠勝任,稍複雜點或應用場景更復雜,那麼推薦 tcpcopy。更復雜,要求更高的流量複製,那隻能咱們本身定製了。
好了,本篇到這結束了,歡迎留言討論,你覺着最佳流量複製方案。
我是DeanWu,一個努力成爲真正SRE的人。
關注公衆號「碼農吳先生」, 可第一時間獲取最新文章。回覆關鍵字「go」「python」獲取我收集的學習資料,也可回覆關鍵字「小二」,加我wx拉你進技術交流羣,聊技術聊人生~