使用tcpcopy導入線上流量進行功能和壓力測試

假設我們要上線一個兩年內不會宕機的先進架構。在上線前,免不了單元測試,功能測試,還有使用ab,webbench等等進行壓力測試。

但這些步驟非生產環境下正式用戶的行爲。或許你會想到灰度上線,但畢竟可能會影響到部分用戶,這怎麼對得起我們兩年內不宕機的承諾呢?

好在網易的 王斌 開發了tcpcopy, 可以導入線上流量進行功能和壓力測試。

tcpcopy介紹

tcpcopy是一種請求複製工具。可以將線上流量拷貝到測試機器,實時的模擬線上環境。在不影響線上用戶的情況下,使用線上流量進行測試,以儘早發現bug。也可以通過放大流量,進行壓力測試,評估系統承載能力。

tcpcopy可以從線上服務器的IP層抓取在線請求的數據包,修改相關屬性,利用raw socket output技術(packet injection 技術之一)將其發送給測試服務器進行測試。

發送到測試服務器的數據包會在TCP/IP協議棧被識別,其中帶有payload(tcp data)的數據包最終進入到測試服務器的上層應用(如nginx),上層應用在處理完請求之後,將響應傳遞給測試服務器的TCP/IP協議棧。

在測試服務器上啓用ip_queue模塊,並使用iptablesIP層將響應結果數據包發往QUEUE(ip_queue)。

測試服務器上運行在用戶空間的攔截程序(intercept進程),通過打開netlink的socket接受內核通過ip_queue所傳遞來的網絡數據包(即上層應用的響應內容)進行裁定,將結果返回內核,進行出隊列的操作。intercept進程默認會丟棄上層應用的響應內容,返回ip header,以釋放tcp連接。

intercept進程也可以通過-x(passlist)參數,不drop指定ip lists發出請求的響應內容。默認drop是爲了:

減少出口帶寬佔用,節約成本不影響客戶端(線上服務)的`TCP/IP`協議棧不會在互聯網上產生ghost數據包

tcpcopy工作流程

如上圖,tcpcopy拷貝一次流量訪問的步驟如下:

① 一個訪問到達線上前端機;② socket數據包在ip層被拷貝了一份傳給tcpcopy進程;③ tcpcopy修改包的目的及源地址,發給目標測試機;④ 拷貝的包到達目標測試機;⑤ 目標測試機的nginx處理訪問,並返回結果;⑥ 返回結果在ip層被截獲、丟棄,由intercpet進程拷貝返回結果的ip header並返回;⑦ ip header被髮送給線上前端機的tcpcopy進程。

安裝和配置

tcpcopy有兩種工作模式:

實時拷貝數據包通過使用tcpdump等抓包生成的文件進行離線(offline)請求重放

如果採用實時拷貝線上流程進行導入的方式,需要分別在線上服務器和測試服務器安裝tcpcopy,對於離線模式,只需要在測試服務器上安裝tcpcopy,編譯時指定 --enable-offline

安裝步驟如下:
wget https://github.com/wangbin579/tcpcopy/archive/0.9.0.tar.gz -O tcpcopy-0.9.0.tar.gz --no-check-certificate
tar zxvf tcpcopy-0.9.0.tar.gz
cd tcpcopy-0.9.0./autogen.sh
./configure --prefix=/usr/local/tcpcopy
make
sudo make install
目標測試機配置

線上服務器拷貝的數據包發送至測試服務器進行處理之後,測試服務器需要通過iptables將響應結果發送至QUEUE(ip_queue),這樣測試服務器上運行的intercept攔截進程才能通過打開的netlinksocket獲取傳遞過來的數據包並進行裁定。所以測試服務器上需要開啓iptables防火牆,並啓用內核模塊ip_queue

modprobe ip_queue
/etc/init.d/iptables start

因爲線上服務器需要和目標測試服務器通信,傳遞請求數據包和控制信息(封裝的ip packet header),所以需要在測試服務器上添加相關iptables防火牆規則。編輯/etc/sysconfig/iptables,添加:

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80-j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 36524-j ACCEPT

然後重啓iptables

/etc/init.d/iptables restart

接着執行:

iptables -I OUTPUT -p tcp --sport 80-j QUEUE

將響應結果發送至QUEUE(ip_queue),從而實現運行在用戶態的進程對相關數據包進行裁定。

相關使用

本文以線上和測試機的web服務都使用80端口,傳遞控制信息使用默認的36524端口爲例。如果使用別的端口,記得修改相關iptables防火牆規則。

離線 offline

1) 在線上服務器抓包

tcpdump -i eth0 tcp and port 80-s 0-w online.pcap

2) 將抓包生成的文件拷貝到測試服務器

3) 在測試服務器上進行執行如下命令進行重放

cd /usr/local/tcpcopy/bin
sudo ./intercept
sudo ./tcpcopy -i /path/online.pcap -x 80-10.16.12.11:80
tcpcopy -i <抓包文件地址>-x <port>-<本地ip>:<port>
在線實時複製 online

1) 在測試服務器上啓動intercept攔截進程

cd /usr/local/tcpcopy/bin
sudo ./intercept

2) 在線上服務器複製流量到測試服務器

cd /usr/local/tcpcopy/bin
sudo ./tcpcopy -x 80-10.16.12.11:80-c 10.16.12.12
tcpcopy -x 服務器應用端口號-測試服務器ip地址:測試服務器應用端口-c 本地服務器ip

reference:

[^1] https://github.com/wangbin579/tcpcopy

[^2] http://www.searchtb.com/2012/05/using-tcpcopy-to-simulate-traffic.html

[^3] http://hi.baidu.com/yacker/item/e6bd5b287fe5a3f150fd8731

[^4] http://blog.yam.com/hn12303158/article/35207136

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章