基於TCPCopy的模擬壓測方案
- 2020 年 2 月 25 日
- 筆記
一、tcpcopy工具介紹
tcpcopy 是一個分散式在線壓力測試工具,可以將線上流量拷貝到測試機器,實時的模擬線上環境,達到在程式不上線的情況下實時承擔線上流量的效果,儘早發現 bug,增加上線信心。
tcpcopy 的優勢在於其實時性及真實性,除了少量的丟包,完全拷貝線上流量到測試機器,真實的模擬線上流量的變化規律。
二、tcpcopy原理

TCPCopy 分為三個角色:
- Online Server(OS):上面要部署 TCPCopy,從數據鏈路層(pcap 介面)抓請求數據包,發包是從IP層發出去;
- Test Server(TS):最新的架構調整把 intercept 的工作從 TS 中 offload 出來。TS 設置路由資訊,把 被測應用 的需要被捕獲的響應數據包資訊路由到 AS;
- Assistant Server(AS):這是一台獨立的輔助伺服器,原則上一定要用同網段的一台閑置伺服器來充當輔助伺服器。AS 在數據鏈路層截獲到響應包,從中抽取出有用的資訊,再返回給相應的 OS 上的 tcpcopy 進程。
數據傳輸流程圖

簡單解釋一下工作原理:
- TCPcopy 從數據鏈路層 copy 埠請求,然後更改目的 ip 和目的埠。
- 將修改過的數據包傳送給數據鏈路層,並且保持 tcp 連接請求。
- 通過數據鏈路層從 online server 發送到 test server。
- 在數據鏈路層解封裝後到達 nginx 響應的服務埠。
- 等用戶請求的數據返回結果後,回包走數據鏈路層。
- 通過數據鏈路層將返回的結果從 test server 發送到 assistant server。註:test server 只有一條默認路由指向 assistant server。
- 數據到達 assistant server 後被 intercept 進程截獲。
- 過濾相關資訊將請求狀態發送給 online server 的 tcpcopy,關閉 tcp 連接。
三、操作步驟
Online Server 上的發包:
OS 默認使用 raw socket output 介面發包,此時發包命令如下:
tcpcopy -x 應用埠-Test Server:Test Server應用埠 -s Assistant Server
例如:
tcpcopy -x 80-192.168.0.246:80 -s 192.168.0.247 -d
此外,新架構還支援通過 pcap_inject(編譯時候增加--enable-dlinject)來發包。
Test Server 上的響應包路由:
需要在 Test Server 上添加靜態路由,確保被測試應用程式的響應包路由到輔助測試伺服器,而不是回包給 Online Server。
route add -net 伺服器所在網段 gw Assistant Server
例如:
route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.247
Assistant Server 上的捕獲響應包:
輔助伺服器要確保沒有開啟路由模式 cat /proc/sys/net/ipv4/ip_forward,為0表示沒有開啟。 輔助伺服器上的 intercept 進程通過 pcap 抓取測試機應用程式的響應包,將頭部抽取後發送給 Online Server 上的 tcpcopy 進程,從而完成一次請求的複製。
intercept -i 網卡名 -F 'tcp and src port 應用埠' -d
例如:
intercept -i ens160 -F 'tcp and src port 80' -d
-i 參數,還可以為any,表示所有網卡
四、tcpcopy搭建
環境說明
角色 | ip | 埠 |
|---|---|---|
Assistant Server | 192.168.0.247 | |
Online Server | 192.168.0.245 | 80 |
Test Server | 192.168.0.246 | 80 |
拓撲圖

運行流程
- tcpcopy運行在線上伺服器上,tcpcopy會把線上伺服器收到的流量,重放給測試伺服器,重放的時候tcpcopy修改了IP數據包的源IP地址(譬如修改源地址為192.168.2.254)。所以,線上伺服器和測試伺服器應該部署相同的服務。
- tcpcopy把源IP偽造成192.168.2.254的包發給了測試伺服器,如此,測試伺服器在處理完tcpcopy發過來的數據以後,會把這些數據包返回給客戶端,即偽造的192.168.2.254。
- 由於沒有192.168.2.254這個地址,我們在測試伺服器添加一條專門的路由,把發往192.168.2.0/24的數據包,都全部轉交給輔助伺服器。
- 為了保證輔助伺服器會接受這些本不屬於自己的,部署在輔助伺服器上的intercept就發揮作用了。輔助伺服器還可以用來把客戶端的請求返回給tcpcopy,但是默認只返迴響應頭部給tcpcopy。輔助伺服器應該類似於黑洞。
intercept安裝
Assistant Server 上的操作:
下載並安裝 intercept 服務端;
# 安裝編譯環境 apt-get install -y build-essential # 安裝pcap依賴包 apt-get install -y libpcap-dev # 下載軟體包 # github地址: http://github.com/session-replay-tools/intercept wget https://github.com/session-replay-tools/intercept/archive/1.0.0.tar.gz -o intercept-1.0.0.tar.gz tar zxvf intercept-1.0.0.tar.gz -C /usr/src cd /usr/src/intercept-1.0.0 ./configure --prefix=/usr/local/intercept-1.0.0 make && make install # 創建軟連接 ln -s /usr/local/intercept-1.0.0/sbin/intercept /usr/bin/intercept # 啟動程式 intercept -i ens160 -F 'tcp and src port 80' -d
注意:必須先安裝 intercept,否則會導致 tcpcopy 啟動時,找不到 intercept
tcpcopy安裝
Online Server 上的操作:
下載並安裝 tcpcopy 客戶端
# 安裝編譯環境 apt-get install -y build-essential # 下載軟體包 # github地址: http://github.com/session-replay-tools/tcpcopy wget https://github.com/session-replay-tools/tcpcopy/archive/v1.1.0.tar.gz -o tcpcopy-1.1.0.tar.gz tar zxvf tcpcopy-1.1.0.tar.gz -C /usr/src cd /usr/src/tcpcopy-1.1.0 ./configure --sbin-path=/usr/local/sbin make && make install # 創建軟連接 ln -s /usr/local/tcpcopy-1.1.0/sbin/tcpcopy /usr/bin/tcpcopy # 啟動程式 tcpcopy -x 80-192.168.0.246:80 -s 192.168.0.247 -d
注意:192.168.0.246 是 Test Server IP地址,192.168.0.247 是 Assistant Server IP地址
Test Server 添加路由
Test Server 上的操作:
添加靜態路由:
route add -net 192.168.0.0/24 gw 192.168.0.247
注意:192.168.2.0/24 是不存在的網路,是一條專門的路由,用於將數據包轉發到Assistant Server 。
192.168.0.247 是 Assistant Server IP地址
測試效果
Online Server 和 Test Server 已經安裝了nginx,如果沒有,請使用以下命令安裝:
apt-get install -y nginx
在客戶端瀏覽器,打開 Online Server 的頁面

登錄到 Online Server ,查看訪問日誌
tail -f /var/log/nginx/access.log # 日誌輸出: 192.168.0.136 - - [27/Apr/2019:12:35:56 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
登錄到 Test Server ,查看訪問日誌
tail -f /var/log/nginx/access.log # 日誌輸出: 192.168.2.254 - - [27/Apr/2019:12:35:56 +0800] "GET / HTTP/1.1" 200 396 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
雖然訪問的是 Online Server ,但是 Test Server 能收到客戶端的訪問請求。說明 intercept 轉發正常
本文參考鏈接:
https://www.cnblogs.com/zhengyun_ustc/p/tcpcopy.html
https://juejin.im/entry/5ac1922d6fb9a028bc2de3fb

