性能工具之常見流量複製工具

一、什麼是流量複製?
我們把用戶訪問系統造成的數據傳輸定義爲流量,那麼在用戶訪問系統的過程中,我們可以把進入和流出的數據複製下來,進行保存,待後續使用,即離線模式,或者轉發到一個新的服務器,立即使用,即在線模式。

二、流量複製的應用
性能測試中我們可以使用諸如 ab, wrk, httperf, locust, JMeter 等工具模擬用戶請求,也可以使用流「流量複製」工具,實時捕捉生產環境流量並導向目標測試系統。同時,這些「流量複製」工具可以支持對真實流量進行放大或縮小。

於是有人說,就是因爲這樣才應該直接用真實流量的方式來做嘛,這樣就不用管業務模型了,直接就有生產的業務模型了。沒錯,只要你能通過生產流量擴大回放的方式實現壓力部分,確實可以不用考慮業務場景了。但這麼做的前提也必須是你的生產流量來源是可以覆蓋想要測試的業務場景的。

流量回放

這裏要批駁一個觀點,就是有些人覺得只有通過生產流量回放的方式,纔是真實地 模擬了線上的流量。事實上,這個觀點是偏頗的。

總結一下,流量複製工具的優勢就是可以將線上流量拷貝到測試機器,實時的模擬線上環境,真實的模擬線上流量的變化規律,達到在程序不上線的情況下實時承擔線上流量的效果。

三、常見的流量複製工具
1、綜述
常見流量複製工具

流量複製工具一般分成這幾類:

基於web 服務器的請求複製
優點:請求多樣化、成本
缺點:不具備通用性、丟失網絡延遲、佔用在線資源比較嚴重
基於應用層的流量複製工具
優點:實現簡單

缺點:但會擠佔線上應用的資源(比如連接資源,內存資源等),還可能會因爲耦合度高而影響正常業務。

基於網絡棧的流量複製工具,直接從鏈路層抓取數據包

優點:應用影響較小

缺點:但是其實現也就相對複雜一些

2、ngx_http_mirror_module
在 Nginx 1.13.4 中引入的插件
它是一種應用層的流量複製工具
該模塊目前只實現了兩個配置指令,用法相當簡單:

location / {
mirror /mirror;
proxy_pass
}

location /mirror {
internal;
proxy_pass http://test_backend$request_uri;
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
每一條 mirror 配置項對應用戶請求的一個副本,我們就可以通過配置多次 mirror 指令來實現 “流量 放大” 的效果。當然,你也可以將多個副本轉發給不同的後端目標系統。

示例配置:

server {
listen 8080;
access_log /home/work/log/nginx/org.log;
root html/org;
}

server {
listen 8081;
access_log /home/work/log/nginx/mir.log ;
root html/mir;
}

upstream backend {
server 127.0.0.1:8080;
}

upstream test_backend {
server 127.0.0.1:8081;
}

server {
listen 80;
server_name localhost;

# original 配置
location / {
# mirror指定鏡像uri爲 /mirror
mirror /mirror;
# off|on 指定是否鏡像請求body部分(開啓爲on,則請求自動緩存;)
mirror_request_body off;
# 指定上游server的地址
proxy_pass http://backend;
}

# mirror 配置
location /mirror {
# 指定此location只能被“內部的”請求調用
internal;
# 指定上游server的地址
proxy_pass http://test_backend$request_uri;
# 設置鏡像流量的頭部
proxy_set_header X-Original-URI $request_uri;
}

}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
流量放大, 配置兩個 mirror 即可:

location / {
mirror /mirror;
mirror /mirror;
proxy_pass http://backend;
}
1.
2.
3.
4.
5.
使用很方便,但是線上  nginx 一般都承載了不止一個業務,修改 nginx 配置後需要 nginx -s reload 來使之生效,這種操作在線上還是儘量需要避免的。

3、TCPCopy
TCPCopy 是一種請求複製(複製基於 TCP 的 packets)工具 ,通過複製在線數據包,修改 TCP/IP 頭部信息,發送給測試服務器,達到欺騙測試服務器的TCP 程序的目的,從而爲欺騙上層應用打下堅實基礎。
TCPCopy 由網易技術部的王斌在王波的工作基礎上中 2010 年開發,並於 2011 年 9 月開源。T
TCPCopy  一般會與 TCPDump 共同使用。
基於 C 語言
地址:https://github.com/session-replay-tools/tcpcopy
stars:3.9k
TCPCopy 由兩部分組成:TCPCopy 和 intercept。TCPCopy 在線上服務器上運行並捕獲在線請求,intercept 運行在輔助服務器上並執行一些輔助工作,例如將響應信息傳遞給 TCPCopy。測試應用程序則在目標服務器上運行。也就是使用上其實還需要一個輔助服務器。

運行邏輯圖

TCPCopy 的主要優勢:

協議無感知,可以透明轉發,能夠支持基於 TCP 的任意應用層協議,如 MySQL,Kafka,Redis 等
實時轉發,延時較低
可以保留原始請求 IP 端口信息,測試服務器可用於統計
同時,也具有以下不足:

無法動態添加多個下游服務器
由於透明轉發,不做協議解析,無法發現數據異常,如部分 TCP 包丟失,測試服務器將收到不完整的數據;此外,也無法對應用層數據進行篩選和修改進行修改
核心組件設計時未進行多線程設計,處理能力存在瓶頸
需要修改 iptables 來丟棄下游服務的回包,用在生產或公共的測試環境存在較大風險
4、GOReplay
Goreplay 是用 Golang 寫的一個 HTTP 實時流量複製工具。功能更強大,支持流量的放大、縮小,頻率限制,還支持把請求記錄到文件,方便回放和分析,也支持和 ElasticSearch 集成,將流量存入 ES 進行實時分析。
GoReplay 不是代理,而是監聽網絡接口上的流量,不需要更改生產基礎架構,而是在與服務相同的計算機上運行 GoReplay 守護程序。
特點:簡單易用
地址:https://github.com/buger/goreplay
stars:14.1k
與 TCPCopy  相比它的架構更簡單,只有一個 gor 組件,如下:

整體架構圖

只需要在生產服務器上啓動一個 gor 進程,它負責所有的工作包括監聽、過濾和轉發。它的設計遵循 Unix 設計哲學:一切都是由管道組成的,各種輸入將數據複用爲輸出。

敲下命令,即可進行流量複製。無需理解複雜的概念。同樣支持在線直接轉發。存儲到文件進行重放,N 倍重放。

sudo ./gor --input-raw :8000 --output-http="http://localhost:8001"
sudo ./gor --input-raw :8000 --output-file=requests.gor
1.
2.
相比 tcpcopy 只能複製 HTTP 和 HTTPS 的流量。使用時編譯很麻煩,一般直接使用編譯好的版本。

一般配合 diffy 一起使用,diffy 提供 diff 能力,可以智能降噪音。

diffy 地址:https://github.com/twitter-archive/diffy
5、TCPReplay
TCPReplay 是一種 pcap 包的重放工具,它可以將用 ethreal、wireshark工具抓下來的包原樣或經過任意修改後重放回去。它允許你對報文做任意的修改(主要是指對2層、3層、4層報文頭),指定重放報文的速度等,這樣tcpreplay 就可以用來複現抓包的情景以定位 bug,以極快的速度重放從而實現壓力測試。
地址:https://github.com/appneta/tcpreplay
stars:765
6、JVM-Sandbox
JVM 沙箱容器,一種 JVM 的非侵入式運行期 AOP 解決方案
需要代碼的編寫,可適用於一些比較定製化的場景
阿里巴巴開源
地址:https://github.com/alibaba/jvm-sandbox
stars:4.3k
整體架構圖:

整體架構圖

沙箱有兩種啓動方式:

使用jvm的attach機制,線上隨時可進行attach
java agent啓動,需要在命令行增加參數,故需要重啓。
流量複製的場景下基本就是選擇 attach了。提供的腳本非常簡單易用,直接在安裝目錄下敲入命令即可。

# 假設目標JVM進程號爲'2343'
./sandbox.sh -p 2343
1.
2.
其他的就是編寫 AOP相關代碼然後編譯成 jar 包放入到安裝目錄。官網的例子非常詳細,有興趣可以瞭解瞭解。

7、Sharingan
Sharingan(中文名:寫輪眼)是一個基於 golang 的流量錄製回放工具,錄製線上真實請求流量進行回放測試,適合項目重構、迴歸測試等。
滴滴開源
地址:https://github.com/didi/sharingan
stars:656
整體架構圖:

整體架構圖

recorder: 流量錄製模塊,錄製流量本地文件存儲、發送流量到錄製agent等。
recorder-agent:流量錄製agent,單獨進程啓動,控制錄製比例、流量存儲等。
replayer: 流量回放模塊,重定向連接到Mock Server、Mock時間、添加流量標識等。
replayer-agent:流量回放agent,單獨進程啓動,查詢流量、查詢/上報噪音、流量diff、批量回放、生成覆蓋率報告等。
8、RDebug
支持 PHP,暫不支持 java
滴滴開源
地址:https://github.com/didi/rdebug/blob/master/README_zh_CN.md
stars:1.1k
整體架構圖:

四、總結
複製請求:通過將一臺機器的請求複製多份發送到指定的壓測機器
適用場景:系統調用量比較小的場景
優點:爲了使得壓測的請求跟真實的業務請求更加接近,在壓測請求的來源方式上,我們嘗試從真實的業務流量進行錄製和回放,採用請求複製的方式來進行壓力測試
缺點:同樣也面臨着處理寫請求髒數據的問題,另外一個缺點複製的請求必須要將響應攔截下來,所以被壓測的這臺機器需要單獨提供,且不能提供正常的服務(不能把響應給到真實的用戶了,比如涉及到發短信郵件之類的)


參考資料:

[1]:《性能測試實戰30講》
[2]:Nginx 的實時流量複製模塊
[3]:Linux流量複製工具
[4]:流量拷貝工具,你用過那幾個?
[5]:流量複製工具
[6]:字節跳動自研線上引流回放系統的架構演進
[7]:流量複製方案對比:Tcpcopy vs Goreplay
[8]:怎麼真實模擬生產環境?什麼是流量複製?用什麼工具?
-----------------------------------
©著作權歸作者所有:來自51CTO博客作者高樓(Zee)的原創作品,請聯繫作者獲取轉載授權,否則將追究法律責任
性能工具之常見流量複製工具
https://blog.51cto.com/u_15181572/6172695

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章