簡介
TCPCopy是一種請求複製(所有基於tcp的packets)工具,可以把線上流量導入到測試系統中去。
曾經套用於網易的廣告投放系統,urs系統,nginx hmux協定等系統,避免了上線帶來的很多問題。
目前此工具已經廣泛套用於各大網際網路公司。
特點
1)實時
2)效果真實
3)低負載,不影響線上
4)操作簡單
5)分散式
6)零成本
7)意義非凡
功能
1)分散式壓力測試工具,利用線上數據,可以測試系統能夠承受的壓力大小(遠比ab壓力測
試工具真實地多),也可以提前發現一些bug
2)普通上線測試,可以發現新系統是否穩定,提前發現上線過程中會出現的諸多問題,讓開
發者有信心上線
3)對比試驗,同樣請求,針對不同或不同版本程式,可以做性能對比等試驗
4)流量放大功能,可以利用多種手段構造無限線上壓力,滿足中小網站壓力測試要求
5)利用TCPCopy轉發傳統壓力測試工具發出的請求,可以增加網路延遲,使其壓力測試更加真實
6)熱備份
7)實戰演習(架構師必備)
使用方法
TCPCopy分為TCPCopyclient和TCPCopyserver。
其中TCPCopyclient運行在線上伺服器上面,用來捕獲線上請求數據包;TCPCopyserver
(監聽連線埠為36524)運行在測試機器上面,在測試伺服器的回響包丟棄之前截獲測試伺服器
的回響包,並通過TCPCopyclient和TCPCopyserver之間的tcp連線傳遞回響包的tcp和ip
頭部信息給TCPCopyclient,以完成TCP互動。
使用方法如下:
TCPCopyserver (root用戶執行)
1)啟動核心模組ip_queue (modprobe ip_queue)
2)設定要截獲的連線埠,並且設定對output截獲
IPTABLES -I OUTPUT -p tcp --sport port -j QUEUE
3)./interception (<0.5)or./intercept (>=0.5)
注意(如果已經啟動ip_queue和已經設定iptables,只需要運行第3項;測試完以後要記得刪除上面設定的iptables條目)
TCPCopyclient (root用戶執行)
tcpcopy 0.5之前版本:
./tcpcopy 本地ip地址1[:本地ip地址2:…] 本地port 遠程ip地址遠程port
注意(本地ip地址列表其實就是客戶端所認為的伺服器ip地址,如果前面有lvs,一般就是lvs的虛擬ip地址)
tcpcopy 0.5及其以後版本
./tcpcopy -x 伺服器套用連線埠號-測試伺服器ip地址:測試伺服器套用連線埠
注意事項
(原始碼轉移到了github,敬請注意)
1)Linux平台,核心2.6+,需要支持netlink機制
2)TCPCopy中的tcpcopy和interception orintercept程式運行需要root許可權
3)interception(intercept 0.5+)在同一台機器只需要運行一個實例,多個實例不支持
4)TCPCopyclient需要連線測試伺服器的36524連線埠,所以要對外開放36524連線埠
5)TCPCopy由於依賴於抓包函數,壓力大的時候,抓包函式本身不可靠,所以會丟包,進而丟失請求
6)由於interception(intercept 0.5+)程式密切跟ip queue核心模組相關,
所以當壓力很大的時候請求丟失率很高,需要最佳化sysctl系統參數才能達到好的效果
(通過cat /proc/net/ip_queue,查看ip queue運行情況,如果Queuedropped的數值
不斷增大,則需要修改ip_queue_maxlen參數,比如echo 4096>/proc/sys/net/ipv4/ip_queue_maxlen;
如果Netlinkdroppedde的數值不斷增大,修改net.core.rmem_max和net.core.wmem_max
參數,比如sysctl -w net.core.rmem_max=16777216和sysctl -w net.core.wmem_max=16777216)
7)對於0.5版本以下的版本,複製同一台機器進程之間的請求,也即LocalRequests,
如果出現Messagetoo long,請設定lo MTU不超過1500,並且在配置檔案中不要
設定127.0.0.1地址,要設定區域網路或者外網地址;0.5版本沒有此問題
8)對於0.5版本以下的版本,TCP segmentation offloading相關問題(要注意網卡tso和GRO
要關閉)如果tcpcopy所抓的數據包大小超過MTU(比如出現Messagetoo long),那么
由於raw socket output的原因,需要你改變線上設定,比如:ethtool -K eth1 tso off ;
ethtool -K eth1 gro off
9)對於0.5版本及其以上版本,如果要複製127.0.0.1發出的請求到另外一台機器,需要設定-c參數
10)測試環境最好和線上環境一致,比如連線都保持keepalive
11)TCPCopy只與ip、tcp層的數據有關,如果請求驗證與tcp層以上的協定有關,則系統不能正常運行。
例如:mysql連線協定,由於許可權認證與tcp層上面的mysql協定有關,所以複製過去的請求會被目
標測試伺服器認為非法請求,這個時候需要針對mysql協定作具體針對性的處理,tcpcopy程式才能正常運行
12)多層架構環境下,測試系統一定要獨立,與線上系統沒有業務關聯,否則會影響線上
13)丟失請求率跟網路狀況有關,最好在區域網路內複製請求
14)本系統不支持域名,只支持ip地址
15)針對長請求(比如上傳檔案),0.5版本以下不是很支持,0.5版本及其以上沒有此問題
16)為了避免不必要的麻煩,關閉的時候先關閉tcpcopy,然後再關閉interception
總結
如果你對上線沒有信心,如果你的單元測試不夠充分,如果你對新系統不夠有把握,如果你對
未來的請求壓力無法預測,如果你想對比諸如apache和nginx的性能,如果你想放大線上流量,TCPCopy可以幫助你解決上述難題。
測試舉例
假設13,14是線上套用伺服器,148是測試伺服器(148配置和13差不多),
本地連線埠和遠程連線埠都是12321(連線埠12321是我們的一個套用,類似於memcached套用)。
我們的目的就是為了確認目前線上伺服器能否承受目前兩倍的壓力。
我們利用TCPCopy0.4進行測試:
目標測試伺服器(148)
# modprobe ip_queue (if not run up)
# iptables -I OUTPUT -p tcp --sport 12321 -j QUEUE (if not set)
# ./interception
線上伺服器(13):
# ./tcpcopy xx.xx.xx.13 12321 xx.xx.xx.148 12321
線上伺服器(14):
# ./tcpcopy xx.xx.xx.14 12321 xx.xx.xx.148 12321
13記錄:GREP 'Tue 11:08'access_0913_11.log |wc -l :89316,每秒處理1489次請求
14記錄:grep 'Tue 11:08'access_0913_11.log |wc -l :89309,每秒處理1488次請求
148記錄:grep 'Tue 11:08'access_0913_11.log |wc -l :178175,每秒處理2969次請求
請求丟失率為:(89316+89309-178175)/(89316+89309)=0.25%
從上面可以看出一台線上伺服器能夠承受目前壓力的兩倍。
我們來看負載情況:
TCPCopyclient自身負載占到12.3%和14%,TCPCopyserver占到17%,從負載來看,均不高。
記憶體也占得不多。