真刀真槍壓測:基于TCPCopy的仿真壓測方案
來自: http://www.cnblogs.com/zhengyun_ustc/p/tcpcopy.html
鄭昀 基于劉勤紅和石雍志的實踐報告 創建于2015/8/13 最后更新于2015/8/19
鄭昀 基于劉勤紅和石雍志的實踐報告 創建于2015/8/13 最后更新于2015/8/19
關鍵詞:壓測、TCPCopy、仿真測試、實時拷貝流量
本文檔適用人員:技術人員
提綱:
- 為什么要做仿真測試
- TCPCopy是如何工作的
- 實作:仿真測試的拓撲
- 實作:操作步驟
- 可能會遇到的問題
- ip_conntrack
- 少量丟包
- 離線重放
- 不提取7層信息
- 觀測的性能指標
0x00,為什么要做仿真測試
線下的傳統壓力測試,難以模擬真實流量,尤其難以模擬正常流量混雜著各色異常流量。所以,線下壓得好好的系統,上線后可能某天突然雪崩, 說好能支撐 5 倍流量的系統重構,也許流量一翻倍就徹底掛了。
但辦法總比問題多。
系統重構或重要變更上線前,可以拷貝線上真實流量,實時模擬線上流量,甚至可以放大真實流量,進行壓力測試,以評估系統承載能力。
反過來也可以這樣,如果線上跑著跑著發現有性能瓶頸,但線下環境難以復現,還不如把真實流量拷貝到線下重放,畢竟線下環境便于上各種排查手段,重放幾遍都行,直到找到問題。
所以本次基于 Varnish 的商品詳情頁靜態化在上線前,做了仿真壓測。
如何實時拷貝線上真實流量呢?
TCPCopy。
2010年,網易技術部的王斌在王波的工作基礎上開發了 TCPCopy - A TCP Stream Replay Tool。2011年9月開源。當前版本號是 1.0.0。很多公司的模擬在線測試都是基于 TCPCopy 做的,如一淘。
TCPCopy 是一種請求復制(復制基于 TCP 的 packets)工具 ,通過復制在線數據包,修改 TCP/IP 頭部信息,發送給測試服務器,達到欺騙測試服務器的TCP 程序的目的,從而為欺騙上層應用打下堅實基礎。
0x01,TCPCopy是如何工作的
王斌講過,基于 Server 的請求回放領域,一般分為離線回放和在線實時復制兩種。
其中請求實時復制,一般可以分為兩類:
1)基于應用層的請求復制 ,
2)基于底層數據包的請求復制。
如果從應用層面進行復制,比如基于服務器的請求復制,實現起來相對簡單,但也存在著若干缺點:
1)請求復制從應用層出發,穿透整個協議棧,這樣就容易擠占應用的資源,比如寶貴的連接資源 ,
2)測試跟實際應用耦合在一起,容易影響在線系統,
3)也因此很難支撐壓力大的請求復制,
4)很難控制網絡延遲。
而基于底層數據包的請求復制,可以做到無需穿透整個協議棧,路程最短的,可以從數據鏈路層抓請求包,從數據鏈路層發包,路程一般的,可以在IP層抓請求包,從IP層發出去,不管怎么走,只要不走TCP,對在線的影響就會小得多。這也就是 TCPCopy 的基本思路。
從傳統架構的 rawsocket+iptable+netlink,到新架構的 pacp+route,它經歷了三次架構調整,現如今的 TCPCopy 分為三個角色:
- Online Server(OS):上面要部署 TCPCopy,從數據鏈路層(pcap 接口)抓請求數據包,發包是從IP層發出去;
- Test Server(TS):最新的架構調整把 intercept 的工作從 TS 中 offload 出來。TS 設置路由信息,把 被測應用 的需要被捕獲的響應數據包信息路由到 AS;
- Assistant Server(AS):這是一臺獨立的輔助服務器,原則上一定要用同網段的一臺閑置服務器來充當輔助服務器。AS 在數據鏈路層截獲到響應包,從中抽取出有用的信息,再返回給相應的 OS 上的 tcpcopy 進程。
請配合下圖1理解:


圖1 三個角色的數據流轉方式
Online Server 上的抓包:
tcpcopy 的新架構在 OS 上抓請求數據包默認采用 raw socket input 接口抓包。王斌則推薦采用 pcap 抓包,安裝命令如下:
./configure --enable-advanced --enable-pcap
make
make install
這樣就可以在內核態進行過濾,否則只能在用戶態進行包的過濾,而且在 intercept 端或者 tcpcopy 端設置 filter(通過 -F 參數,類似 tcpdump 的 filter),達到起多個實例來共同完成抓包的工作,這樣可擴展性就更強,適合于超級高并發的場合。
為了便于理解 pcap 抓包,下面簡單描述一下 libpcap 的工作原理。
一個包的捕捉分為三個主要部分:
- 面向底層包捕獲,
- 面向中間層的數據包過濾,
- 面向應用層的用戶接口。
這與 Linux 操作系統對數據包的處理流程是相同的(網卡->網卡驅動->數據鏈路層->IP層->傳輸層->應用程序)。包捕獲機制是 在數據鏈路層增加一個旁路處理(并不干擾系統自身的網絡協議棧的處理),對發送和接收的數據包通過Linux內核做過濾和緩沖處理,最后直接傳遞給上層應 用程序。如下圖2所示:
Online Server 上的發包:
如圖1所示,新架構和傳統架構一樣,OS 默認使用 raw socket output 接口發包,此時發包命令如下:
./tcpcopy -x 80-測試機IP:測試機應用端口 -s 服務器IP -i eth0
其中 -i 參數指定 pcap 從哪個網卡抓取請求包。
此外,新架構還支持通過 pcap_inject(編譯時候增加--enable-dlinject)來發包。
Test Server 上的響應包路由:
需要在 Test Server 上添加靜態路由,確保被測試應用程序的響應包路由到輔助測試服務器,而不是回包給 Online Server。
Assistant Server 上的捕獲響應包:
輔助服務器要確保沒有開啟路由模式 cat /proc/sys/net/ipv4/ip_forward,為0表示沒有開啟。
輔助服務器上的 intercept 進程通過 pcap 抓取測試機應用程序的響應包,將頭部抽取后發送給 Online Server 上的 tcpcopy 進程,從而完成一次請求的復制。
0x02,實作:仿真測試的拓撲
下面將列出本次仿真測試的線上環境拓撲圖。
環境如下: - Online Server
- 4個生產環境 Nginx
- 172.16.***.110
- 172.16.***.111
- 172.16.***.112
- 172.16.***.113
- Test Server
- 一個鏡像環境的 Nginx
- 172.16.***.52
- Assistant Server
- 鏡像環境里的一臺獨立服務器
- 172.16.***.53
拓撲如圖3所示:


圖3 壓測環境拓撲
它的數據流轉順序如下圖4所示:


圖4 壓測環境的數據流轉順序
0x03,實作:操作步驟
下面分別列出在 Online Server/Test Server/Assistant Server 上的操作步驟。
3.1 Online Server 上的操作:
下載并安裝 tcpcopy 客戶端;
git clone http://github.com/session-replay-tools/tcpcopy
./configure
make && make install
安裝完成后的各結構目錄:
Configuration summary
tcpcopy path prefix: "/usr/local/tcpcopy"
tcpcopy binary file: "/usr/local/tcpcopy/sbin/tcpcopy"
tcpcopy configuration prefix: "/usr/local/tcpcopy/conf"
tcpcopy configuration file: "/usr/local/tcpcopy/conf/plugin.conf"
tcpcopy pid file: "/usr/local/tcpcopy/logs/tcpcopy.pid"
tcpcopy error log file: "/usr/local/tcpcopy/logs/error_tcpcopy.log"
運行 tcpcopy 客戶端,有幾種可選方式:
./tcpcopy -x 80-172.16.***.52:80 -s 172.16.***.53 -d #全流量復制
./tcpcopy -x 80-172.16.***.52:80 -s 172.16.***.53 -r 20 -d #復制20%的流量
./tcpcopy -x 80-172.16.***.52:80 -s 172.16.***.53 -n 2 -d #放大2倍流量
3.2 Test Server 上的操作:
添加靜態路由:
route add -net 0.0.0.0/0 gw 172.16.***.53
3.3 Assistant Server 上的操作:
下載并安裝 intercept 服務端;
git clone http://github.com/session-replay-tools/intercept
./configure
make && make install
安裝完成后的各結構目錄:
Configuration summary
intercept path prefix: "/usr/local/intercept"
intercept binary file: "/usr/local/intercept/sbin/intercept"
intercept configuration prefix: "/usr/local"
intercept configuration file: "/usr/local/intercept/"
intercept pid file: "/usr/local/intercept/logs/intercept.pid"
intercept error log file: "/usr/local/intercept/logs/error_intercept.log"
運行 intercept 服務端;
./intercept -i eth0 -F 'tcp and src port 80' -d


圖5 生產環境和鏡像環境數據傳輸流程圖
對照上圖5,再簡單解釋一下工作原理:
- TCPcopy 從數據鏈路層 copy 端口請求,然后更改目的 ip 和目的端口。
- 將修改過的數據包傳送給數據鏈路層,并且保持 tcp 連接請求。
- 通過數據鏈路層從 online server 發送到 test server。
- 在數據鏈路層解封裝后到達 nginx 響應的服務端口。
- 等用戶請求的數據返回結果后,回包走數據鏈路層。
- 通過數據鏈路層將返回的結果從 test server 發送到 assistant server。注:test server 只有一條默認路由指向 assistant server。
- 數據到達 assistant server 后被 intercept 進程截獲。
- 過濾相關信息將請求狀態發送給 online server 的 tcpcopy,關閉 tcp 連接。
0x04,可能會遇到的問題
王斌自己講:要想用好 tcpcopy,需要熟悉系統知識,包括如何高效率抓包,如何定位系統瓶頸,如何部署測試應用系統,如何抓包分析。常見問題有:1)部署測試系統不到位, 耦合線上系統,2)忽視系統瓶頸問題,3)不知道如何定位問題,4)資源不到位,資源緊張引發的問題 。
1)ip_conntrack
2014年6月,微博的唐福林曾說:“Tcpcopy 引流工具是線上問題排查的絕佳之選,但使用者很少有人去關注開啟 tcpcopy 服務時,同時會開啟 ip_conntrack 內核模塊,這個模塊負責追蹤所有 tcp 鏈接的狀態,而且它的內部存儲有長度限制,一旦超過,所有新建鏈接都會失敗。”
王斌則 回應說:“開啟 tcpcopy,自身不會去開啟 ip_conntrack 內核模塊。開不開啟 ip_conntrack 內核模塊,是用戶自己決定的,跟 tcpcopy 沒關系。”他 還建議:“ 當 連接數量非常多的時候,本身就應該關閉 ip_conntrack,否則嚴重影響性能。至于 tcpcopy,默認是從 ip 層發包的,所以也會被 ip_conntrack 干涉,文檔中也有描述,其實也可以采用 --enable-dlinject 來發包,避開ip層的ip_conntrack。如果沒有報“ip_conntrack: table full, dropping packet”,一般無需去操心ip_conntrack。”以及“線上連接不多的場合,開啟 ip_conntrack 并沒有問題。線上連接比較多的場合,最好關閉 ip_conntrack,或者對線上應用系統端口設置 NOTRACK,至少我周圍的系統都是這樣的,這是為性能考慮,也是一種好的運維習慣。”
2)少量丟包
如何發現 TCPCopy 丟包多還是少呢?
王斌自己稱,在某些場景下,pcap 抓包丟包率會遠高于 raw socket 抓包,因此最好利用 pf_ring 來輔助或者采用 raw socket 來抓包。
丟包率需要在測試環境中按照定量請求發送進行對比才能展開計算,另外還需要對日志內容進行分析,有待測試。
3)離線重放
tcpcopy 有兩種工作模式:
1)實時拷貝數據包;
2)通過使用 tcpdump 等抓包生成的文件進行離線(offline)請求重放。
本次仿真測試,沒有試驗成功第二種工作模式,留待以后進一步研究。 4)不提取 7 層信息
會議上曾提出按域名區分拷貝流量,省得把不在本次壓測范圍內的工程打掛,但 tcpcopy 的原理是在 ip 層拷貝,不提取 7 層的信息,也就是說,在我們的 Nginx*4 上部署 TCPCopy,只能是將所有流量拷貝到鏡像環境的 Nginx 上。反正沒有配置對應的 server,或者 server 停掉,這種處理不了的流量就丟棄掉。
0x05,觀測的性能指標
仿真壓測時,需要記錄下 Test Server 以及后端各種被壓工程的性能指標。
本次壓測,我們記錄的指標有:
- Java 工程的訪問次數,響應時間,平均響應時間,調用成功或失敗,Web端口連接數;
- Web容器的 thread、memory 等情況;
- 虛擬機的 CPU-usage、Load-avg、io-usage 等;
- memcached/redis 等緩存集群的命中率等;
參考資源:
1,2014, 使用tcpcopy導入線上流量進行功能和壓力測試;
2,2012,一淘: 利用tcpcopy引流做模擬在線測試;
3, 王斌的微博;
4,2013, tcpcopy架構漫談;
5,2014,網易QA, Tcpcopy兩種架構原理詳解(連載二) ;
本文由用戶 nf83 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!