流量複製-----tcpcopy的使用(1)

前言

TCPCopy是基於網絡棧,TCP協議的流量複製,常用的場景是把線上流量複製到測試環境,模擬線上用戶操作,讓測試機和真實的用戶交互,讓測試環境在正式灰度前暴露問題,用來排查線下不容易重現的問題,或者對測試環境做壓力測試,增加上線信心。
除了佔用額外的CPU,內存和帶寬外,TCPCopy對生產系統幾乎沒有影響。此外,在請求多樣性,網絡延遲和資源佔用方面,再現的工作負載與生產工作負載相似。
Github參考地址:https://github.com/session-replay-tools/tcpcopy

原理

tcpcopy 經歷了三次架構調整,這三次架構的基本原理都一樣,本質是利用在線數據包信息,模擬tcp客戶端協議棧,欺騙測試服務器的上層應用服務。由於tcp交互是相互的,一般情況下需要知道測試服務器的響應數據包信息,才能利用在線請求數據包,構造出適合測試服務器的請求數據包,因此只要基於數據包的方式,無論怎麼實現(除非是tcp協議改的面目全非),都需要返回響應包的相關信息。 三種架構的差別就在於在什麼地方截獲響應包。
三種架構的區別:https://blog.csdn.net/wangbin579/article/details/8949315
TCPCopy由兩部分組成: tcpcopy和intercept。tcpcopy負責抓包和發包工作,而intercept負責截獲應答包

架構描述

在這裏插入圖片描述
tcpcopy包含三部分:online server(線上服務器)、assistant server(輔助服務器)、target server(目標服務器即測試服務器)
訪問流程(官方說明)
1、一個訪問請求到達線上內核後端機;
2、socket 包在 IP 層被拷貝了一份傳給tcpcopy 進程;
3、tcpcopy 修改包的目的及源地址,發給測試內核後端機;
4、拷貝的包到達測試內核後端機;
5、測試內核後端機的推薦內核處理訪問,並返回結果;
6、返回結果在 IP 層被截獲、丟棄,由 intercept 拷貝返回結果的 IP header 返回;
7、IP header 被髮送給線上內核後端機的 tcpcopy 進程。

通俗解釋:
假如三個機器IP如下:
線上服務器 --> 192.168.124.105
測試服務器 --> 192.168.124.68
輔助服務器 --> 192.168.124.180

  1. tcpcopy運行在線上服務器上,tcpcopy會把線上服務器收到的流量,重放給測試服務器,重放的時候tcpcopy修改了IP數據包的源IP地址(譬如修改源地址爲192.168.2.254)。所以,線上服務器和測試服務器應該部署相同的服務。
  2. tcpcopy把源IP僞造成192.168.2.254的包發給了測試服務器,如此,測試服務器在處理完tcpcopy發過來的數據以後,會把這些數據包返回給客戶端,即僞造的192.168.2.254。
  3. 由於沒有192.168.2.254這個地址,我們在測試服務器添加一條專門的路由,把發往192.168.2.0/24的數據包,都全部轉交給輔助服務器。
  4. 爲了保證輔助服務器會接受這些本不屬於自己的,部署在輔助服務器上的intercept就發揮作用了。輔助服務器還可以用來把客戶端的請求返回給tcpcopy,但是默認只返回響應頭部給tcpcopy。輔助服務器類似於黑洞。即:數據到達 assistant server 後被 intercept 進程截獲。過濾相關信息將請求狀態發送給 online server 的 tcpcopy,關閉 tcp 連接

詳細介紹

工作模式:
1 線上實時拷貝數據包
2 通過使用tcpdump等抓包生成的文件進行離線(offline)請求重放
如果採用實時拷貝線上流程進行導入的方式,需要分別在線上服務器和測試服務器安裝tcpcopy,對於離線模式,只需要在測試服務器上安裝tcpcopy,編譯時指定 --enable-offline。
其中請求實時複製,一般可以分爲兩類:
1)基於應用層的請求複製 ,
2)基於底層數據包的請求複製。
如果從應用層面進行復制,比如基於服務器的請求複製,實現起來相對簡單,但也存在着若干缺點:
1)請求複製從應用層出發,穿透整個協議棧,這樣就容易擠佔應用的資源,比如寶貴的連接資源
2)測試跟實際應用耦合在一起,容易影響在線系統,
3)也因此很難支撐壓力大的請求複製,
4)很難控制網絡延遲。

而基於底層數據包的請求複製,可以做到無需穿透整個協議棧,路程最短的,可以從數據鏈路層抓請求包,從數據鏈路層發包,路程一般的,可以在IP層抓請求包,從IP層發出去,不管怎麼走,只要不走TCP,對在線的影響就會小得多。這也就是 TCPCopy 的基本思路,目前基本使用第二個。
使用場景:

  1. 壓力測試
  2. 迴歸測試
  3. 線上問題重現

安裝部署

略(以二線部署手冊爲準)
參考地址:https://github.com/session-replay-tools/tcpcopy
使用方法
一、 實時複製流量
tcpcopy -x 8000-192.168.124.68:8000 -s 192.168.124.180 -c 192.168.2.254 -n 2 -d
• -x, 是指本機8000端口的流量copy到192.168.124.68的8000端口
• -s, 指定intercept機器的地址,tcpcopy要和intercept建立連接
• -c 僞裝地址,在把流量複製到測試服務器的時候,修改數據包的源地址爲192.168.2.254,這樣方便指定路由。也可以寫成192.168.2.x,這樣源地址就是指定網段中的地址了。
• -n 流量放大倍數,如果不是壓測目的就不用指定這個參數。
-d 以守護模式運行。
其他常用參數說明
• -i 其中file 是pcap 離線文件的文件路徑
• -o < device,> 指定從哪個網卡設備上發包
需注意如下事項:
1)此參數只有在編譯./configure --enable-dlinject 模式下才有效
–enable-dlinject說明此模式是爲了支持tcpcopy 能夠從數據鏈路層發送請求數據包。從數據鏈路層發包的好處是不會去幹擾在線服務器的IP 模塊(比如不會去幹擾ip_conntrack 模塊),但不好的地方是需要自己去解決路由問題。
2)-o 參數需要設置成與轉發IP 地址相匹配的網卡設備
tcpcopy -o eth0 -x 12345-221.130.189.25:12345
比如:轉發IP 地址爲外網IP 地址,那麼-o 參數就設置成外網網卡設備的名稱
• -I 參數離線模式下,降低請求之間的間隔,對稀疏的請求訪問,其加速非常有效果
./tcpcopy -x 80-192.168.0.2:8080 -I 1000 -i online.pcap
對請求之間間隔1000毫秒以外的請求進行加速
注意只有在離線模式下有效
• -a 參數
離線模式下,對請求數據包的訪問進行加速
舉例:假設online.pcap 文件爲在線請求數據包的抓包文件,時間爲60 分鐘
./tcpcopy -x 80-192.168.0.2:8080 -a 2 -i online.pcap
執行此命令後,離線回放加速了2 倍,只需要30分鐘,離線回放就能完成
需要注意的是,此命令只有在離線模式下才有效,而且-a 參數設置越大,丟請求的概率
也越大。

• -r 參數
如果你想複製在線服務器應用的部分流量,可以採用-r 參數來實現,參數範圍是1~99,其它值都是全流量複製。
舉例:
./tcpcopy -x 80-192.168.0.2:8080 -r 20
這裏tcpcopy 複製在線服務器8080 端口應用的20%流量給後端服務器,需要注意的是
20%是根據session(這裏session 是由客戶端IP,客戶端端口決定)來統計的。
-r 參數常見於對測試應用進行profile 的場合或者測試服務器配置不如在線服務器的場合

二、離線複製流量
使用tcpdump抓包
tcpdump -i eth0 -w test.pcap tcp and port 8000 -c 100
流量回放
tcpcopy -x 8000-192.168.124.68:8000 -s 192.168.124.180 -c 192.168.2.254 -i test.pcap
阿里雲環境下的TCP Copy環境部署參考
雲環境下,安全策略可能會干擾測試的進行。按物理機步驟部署會出現大量TCP SYN_RECV狀態,需要採用如下步驟可以規避麻煩:

  1. 測試機器和intercept部署到一臺機器
  2. tcpcopy端-c參數採用tcpcopy所在的線上機器ip地址
  3. 在線上機器設置iptables黑洞來過濾掉測試服務器的響應包
  4. iptables -I INPUT -p tcp --sport 測試服務的端口 -j DROP -s 測試服務所在機器的ip地址
  5. 不要在測試服務器設置路由,否則會受到干擾
    測試結果
    在線上服務器開啓tcpcopy: # /opt/tcpcopy/sbin/tcpcopy -x 8000-192.168.124.68:8000 -s 192.168.124.180 -c 192.168.2.254 -n 2 -d
    在另外一臺機器上,向線上服務器發起請求,然後查看兩個HTTP服務器的實時日誌,
    線上服務器的結果:

發起了兩次請求,由於url不存在,返回了404的HTTP Code。再看測試服務器:

在測試服務器上,請求變成了四次,明顯看到流量被放大了1倍。效果正如預期。除此之外,還可以看到日誌中的客戶端IP也不一樣。在原始的請求中,解析出來了主機名爲Matrix3,而在測試機器上,客戶端IP是192.168.2.254,就是我們捏造的IP,注意僞造IP的時候,一定要避免環境中存在的IP和常用的IP。
注意
• 輔助服務器要扮演成一個黑洞,所以不能開啓ip_forward
• 在請求會修改數據的地方,譬如修改數據庫,如果配置不當,可能導致數據被重複修改多次。
佔用cpu內存空間實例(實例有點老,但):

注意事項

  1. 僅在Linux(內核2.6或更高版本)上進行了測試
  2. 不支持使用SSL/TLS協議的,比如加密協議https等
  3. 可能會丟包:線上機器,測試機器以及輔助機器部署在同一個網段,或者使用代理,可以降低丟包率
  4. 需要root權限和CAP_NET_RAW功能(CAP_NET_RAW:允許使用原始套接字)
  5. TCPCopy現在僅支持客戶端啓動的連接
  6. ip_forward不應在助手服務器上設置
    影響因素
    有幾個因素可能影響TCPCopy,以下部分將詳細介紹。
    1.捕獲接口
    默認情況下,tcpcopy使用原始套接字輸入接口來捕獲在線服務器上網絡層的數據包。當系統繁忙時,系統內核可能會丟失一些數據包。
    如果使用“ --pcap-capture” 配置tcpcopy,則tcpcopy可以在數據鏈路層捕獲數據包,還可以過濾內核中的數據包。使用PF_RING,tcpcopy在使用pcap捕獲時將丟失更少的數據包。
    捕獲請求的最佳方法可能是通過交換機鏡像入口數據包,然後通過負載平衡器將巨大的流量分配到多臺計算機。
    2.發送接口
    默認情況下,tcpcopy使用原始套接字輸出接口將網絡層的數據包發送到目標服務器。如果要避免ip_conntrack問題或獲得更好的性能,請使用“ --pcap-send” 配置tcpcopy,然後使用適當的參數tcpcopy可以在數據鏈路層將數據包發送到目標服務器。
    3.在通往目標服務器的途中
    通過tcpcopy發送數據包時,它在到達目標服務器之前可能會遇到很多挑戰。由於數據包中的源IP地址仍然是最終用戶的IP地址(默認情況下),而不是在線服務器的IP地址,因此某些安全設備可能會將其用於無效或僞造的數據包,並將其丟棄。在這種情況下,當您使用tcpdump捕獲目標服務器上的數據包時,將不會捕獲來自預期最終用戶的數據包。要知道您是否處於這種情況下,可以選擇同一網段中的目標服務器進行測試。如果數據包可以在同一網段中成功發送到目標服務器,但跨網段未成功發送,則您的數據包可能會中途丟失。
    爲解決此問題,我們建議在同一網段的服務器上部署tcpcopy,目標應用程序和攔截程序。在同一網段中的代理服務器的幫助下,還有另一種解決方案。tcpcopy可以將數據包發送到代理,然後代理將相應的請求發送到另一個網段中的目標服務器。
    請注意,在同一網段中的一臺虛擬機上部署目標服務器的應用程序可能會遇到上述問題。
    4.目標服務器的操作系統
    目標服務器可以設置rpfilter,它將檢查數據包中的源IP地址是否是僞造的。如果是,則該數據包將在網絡層被丟棄。
    儘管目標服務器上的tcpdump可以捕獲數據包,但目標服務器仍未收到任何請求,則應檢查是否有相應的rpfilter設置。如果已設置,則必須刪除相關設置以使數據包通過網絡層。
    還有其他導致tcpcopy無法正常工作的原因,例如iptables設置問題。
    5.目標服務器上的應用程序
    目標服務器上的應用程序可能無法及時處理所有請求。一方面,應用程序中的錯誤可能會使請求長時間不響應。另一方面,TCP層之上的某些協議可能只處理套接字緩衝區中的第一個請求,而使套接字緩衝區中的其餘請求保持未處理狀態。
    6.助手服務器的操作系統
    您不應將ip_forward設置爲true,否則助手服務器不能充當黑洞。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章