假設我們要上線一個兩年内不會當機的先進架構。在上線前,免不了單元測試,功能測試,還有使用ab,webbench等等進行壓力測試。
但這些步驟非生産環境下正式使用者的行為。或許你會想到灰階上線,但畢竟可能會影響到部分使用者,這怎麼對得起我們兩年内不當機的承諾呢?
好在網易的 王斌 開發了tcpcopy, 可以導入線上流量進行功能和壓力測試。
tcpcopy介紹
tcpcopy是一種請求複制工具。可以将線上流量拷貝到測試機器,實時的模拟線上環境。在不影響線上使用者的情況下,使用線上流量進行測試,以盡早發現bug。也可以通過放大流量,進行壓力測試,評估系統承載能力。
tcpcopy可以從線上伺服器的IP層抓取線上請求的資料包,修改相關屬性,利用raw socket output技術(packet injection 技術之一)将其發送給測試伺服器進行測試。
發送到測試伺服器的資料包會在TCP/IP協定棧被識别,其中帶有payload(tcp data)的資料包最終進入到測試伺服器的上層應用(如nginx),上層應用在處理完請求之後,将響應傳遞給測試伺服器的TCP/IP協定棧。
在測試伺服器上啟用ip_queue子產品,并使用iptables在IP層将響應結果資料包發往QUEUE(ip_queue)。
測試伺服器上運作在使用者空間的攔截程式(intercept程序),通過打開netlink的socket接受核心通過ip_queue所傳遞來的網絡資料包(即上層應用的響應内容)進行裁定,将結果傳回核心,進行出隊列的操作。intercept程序預設會丢棄上層應用的響應内容,傳回ip header,以釋放tcp連接配接。
intercept程序也可以通過-x(passlist)參數,不drop指定ip lists送出請求的響應内容。預設drop是為了:
1 減少出口帶寬占用,節約成本
2 不影響用戶端(線上服務)的<code>TCP/IP</code>協定棧
3 不會在網際網路上産生ghost資料包
tcpcopy工作流程
如上圖,tcpcopy拷貝一次流量通路的步驟如下:
① 一個通路到達線上前端機;
② socket資料包在ip層被拷貝了一份傳給tcpcopy程序;
③ tcpcopy修改包的目的及源位址,發給目标測試機;
④ 拷貝的包到達目标測試機;
⑤ 目标測試機的nginx處理通路,并傳回結果;
⑥ 傳回結果在ip層被截獲、丢棄,由intercpet程序拷貝傳回結果的ip header并傳回;
⑦ ip header被發送給線上前端機的tcpcopy程序。
安裝和配置
tcpcopy有兩種工作模式:
1 實時拷貝資料包
2 通過使用tcpdump等抓包生成的檔案進行離線(offline)請求重放
如果采用實時拷貝線上流程進行導入的方式,需要分别線上上伺服器和測試伺服器安裝tcpcopy,對于離線模式,隻需要在測試伺服器上安裝tcpcopy,編譯時指定 --enable-offline。
安裝步驟如下:
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攔截程序
2) 線上上伺服器複制流量到測試伺服器
sudo ./tcpcopy -x 80-10.16.12.11:80 -c 10.16.12.12
tcpcopy -x 伺服器應用端口号-測試伺服器ip位址:測試伺服器應用端口 -c 本地伺服器ip
reference:
本文轉自Tenderrain 51CTO部落格,原文連結:http://blog.51cto.com/tenderrain/2067607,如需轉載請自行聯系原作者