鄭昀 基於劉勤紅和石雍志的實踐報告 建立於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所示:
圖2 libpcap的三部分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
- 4個生產環境 Nginx
- Test Server
- 一個映象環境的 Nginx
- 172.16.***.52
- 一個映象環境的 Nginx
- 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兩種架構原理詳解(連載二) ;
-EOF-
歡迎訂閱我的微信訂閱號『老兵筆記』,請掃描二維碼關注: