nginx mirror 流量鏡像的具體使用
流量鏡像 (Traffic Mirroring),也稱為流量影子 (Traffic Shadowing),是一種強大的、無風(fēng)險的測試應(yīng)用版本的方法,它將實時流量的副本發(fā)送給被鏡像的服務(wù)。
采用這種方法,您可以搭建一個與原環(huán)境類似的環(huán)境以進(jìn)行驗收測試,從而提前發(fā)現(xiàn)問題。由于鏡像流量存在于主服務(wù)關(guān)鍵請求路徑帶外,終端用戶在測試全過程不會受到影響。
nginx_http_mirror_module模塊特性
利用 mirror 模塊,可以將線上實時流量拷貝至其他環(huán)境同時不影響源站請求的響應(yīng),因為 Nginx 會丟棄 mirror 的響應(yīng)
mirror 模塊可用于以下幾個場景:
- 通過預(yù)生產(chǎn)環(huán)境測試來觀察新系統(tǒng)對生產(chǎn)環(huán)境流量的處理能力
- 復(fù)制請求日志以進(jìn)行安全分析
- 復(fù)制請求用于數(shù)據(jù)科學(xué)研究
將生產(chǎn)環(huán)境的流量拷貝到預(yù)上線環(huán)境或測試環(huán)境的好處:
- 可以驗證功能是否正常,以及服務(wù)的性能;
- 用真實有效的流量請求去驗證,又不用造數(shù)據(jù),不影響線上正常訪問;
- 這跟灰度發(fā)布還不太一樣,鏡像流量不會影響真實流量;
- 可以用來排查線上問題;
- 重構(gòu),假如服務(wù)做了重構(gòu),這也是一種測試方式;
Nginx的流量鏡像是只復(fù)制鏡像,發(fā)送到配置好的后端,但是后端響應(yīng)返回到nginx之后,nginx是自動丟棄掉的,這個特性就保證了鏡像后端的不管任何處理不會影響到正??蛻舳说恼埱?/strong>。
錯誤的說法:復(fù)制的鏡像請求和原始請求是相關(guān)聯(lián)的,只要鏡像請求沒有處理完成,原始請求就會被阻塞。
經(jīng)過測試,鏡像 的接口很慢,或者500都不影響原始請求的響應(yīng)。
Nginx 如何實現(xiàn)流量鏡像
當(dāng)請求到達(dá) Nginx 時,如果 Nginx 開啟了流量鏡像功能,就會將請求復(fù)制一份,并根據(jù) mirror location 中的配置來處理這份復(fù)制的請求。復(fù)制的鏡像請求和原始請求是沒有關(guān)聯(lián),鏡像 的接口很慢,或者500都不影響原始請求的響應(yīng)。
Nginx 流量鏡像配置
upstream bd_interface {
server 10.1.1.1:8080;
check interval=3000 rise=2 fall=5 timeout=2000 type=http;
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx http_4xx;
}
#鏡像流量也可以負(fù)載均衡
upstream mirror_interface1 {
server 10.2.1.1:9090;
check interval=3000 rise=2 fall=5 timeout=2000 type=http;
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx http_4xx;
}
#鏡像流量也可以負(fù)載均衡
upstream mirror_interface2 {
server 10.3.1.1:9090;
check interval=3000 rise=2 fall=5 timeout=2000 type=http;
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx http_4xx;
}
server {
listen 80;
server_name xxx;
access_log logs/bd-interface.log access_json;
charset utf8;
client_max_body_size 800M;
gzip on;
gzip_min_length 5k;
gzip_comp_level 8;
gzip_types application/javascript text/css text/javascript image/jpeg image/gif image/png application/json;
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
location / {
mirror /mirror1;
mirror /mirror2; #兩份鏡像
mirror_request_body on;
proxy_http_version 1.1;
proxy_pass http://bd_interface;
proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 20;
proxy_read_timeout 1000;
proxy_send_timeout 300;
proxy_buffer_size 64k;
proxy_buffers 32 32k;
proxy_busy_buffers_size 128k;
}
location /mirror1 {
internal; #只有內(nèi)部請求可以調(diào)用
proxy_pass http://127.0.0.1:10991$request_uri; #配置鏡像日志,mirror本身不支持日志
proxy_set_header X-Original-URI $request_uri;
}
location /mirror2 {
internal; #只有內(nèi)部請求可以調(diào)用
proxy_pass http://127.0.0.1:10992$request_uri; #配置鏡像日志,mirror本身不支持日志
proxy_set_header X-Original-URI $request_uri;
}
#狀態(tài)監(jiān)控
location /nginx_status {
stub_status on;
access_log off;
}
#狀態(tài)監(jiān)控
location /check_status {
check_status;
access_log off;
}
}
server {
listen 10992;
server_name 127.0.0.1;
client_max_body_size 800M;
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
access_log logs/bd-interface.log access_json;
location / {
proxy_http_version 1.1; #流量和并發(fā)大時必須使用http1.1
proxy_pass http://mirror_interface2;
}
}
server {
listen 10991;
server_name 127.0.0.1;
client_max_body_size 800M;
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
access_log logs/bd-interface.log access_json;
location / {
proxy_http_version 1.1;#流量和并發(fā)大時必須使用http1.1
proxy_pass http://mirror_interface1;
}
}Nginx流量拷貝的注意事項
mirror_request_body/proxy_pass_request_body與Content-Length需配置一致。如果mirror_request_body或者proxy_pass_request_body設(shè)置為 off,則Content-Length必須設(shè)置為"",因為nginx(mirror_request_body)或tomcat(mirror_request_body)處理post請求時,會根據(jù)Content-Length獲取請求體,如果Content-Length不為空,而由于mirror_request_body或者proxy_pass_request_body設(shè)置為off,處理方以為post有內(nèi)容,當(dāng)request_body中沒有,處理方會一直等待至超時。mirror_request_body為off,nginx會報upstream請求超時;proxy_pass_request_body為off,tomcat會報異常。
案例一
最近某個機(jī)房a空間不夠,考慮遷移到分公司的機(jī)房b,從當(dāng)前機(jī)房a到新機(jī)房b有將近2000公里,往返時延41ms。而老機(jī)房a在內(nèi)網(wǎng)環(huán)境下延小于1ms。拍腦袋計劃使用nginx流量鏡像雙寫到a和b兩個機(jī)房,反向代理到a機(jī)房,鏡像到b機(jī)房。先不說方案的問題,比如無法保證數(shù)據(jù)一致性。僅僅從流量復(fù)制來說就有問題。大流量高并發(fā)測試發(fā)現(xiàn),nginx報400的錯誤,kafka客戶端報超時的錯誤,并發(fā)稍微增加就會出現(xiàn)這兩種報錯,到b機(jī)房流量的吞吐量遠(yuǎn)不及a機(jī)房。
錯誤如下所示:


原因:
使用nginx mirror進(jìn)行流量鏡像,壓測時發(fā)現(xiàn),情況1(反向代理到機(jī)房a,流量鏡像到機(jī)房b),kafka客戶端報超時錯誤,nginx代理報400錯誤,推測主要原因是:到a機(jī)房延時1ms, 到b機(jī)房延時41ms, 在情況1時,假設(shè)a服務(wù)端每秒處理10個請求,b由于延時較長,導(dǎo)致請求一定程度的堆積(壓測時發(fā)送的請求速度是以a的消費能力為準(zhǔn)的,鏡像到b只是順帶著做轉(zhuǎn)發(fā)),結(jié)果就是b服務(wù)端每秒鐘要處理的請求>10個,處理不過來拋出錯誤。
反向佐證,如果是情況2(直連b服務(wù)),情況3(只反向代理到b),情況4(反向代理到b,同時流量鏡像到a),情況5(情況1在并發(fā)請求數(shù)較小時)都不會出現(xiàn)報錯的問題。
參考文章
到此這篇關(guān)于nginx mirror 流量鏡像的具體使用的文章就介紹到這了,更多相關(guān)nginx mirror 流量鏡像內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
把ImageMagic庫編譯進(jìn)nginx服務(wù)器的一些必要配置
這篇文章主要介紹了把ImageMagic庫編譯進(jìn)nginx服務(wù)器的一些必要配置,本文給出了操作步驟和配置參數(shù)示例,需要的朋友可以參考下2015-06-06
記錄Nginx服務(wù)器的Split Clients模塊配置過程
這篇文章主要介紹了Nginx服務(wù)器的Split Clients模塊的配置過程記錄,ngx-http-split-clients模塊用于切分客戶端連接,需要的朋友可以參考下2016-01-01
使用Nginx實現(xiàn)端口轉(zhuǎn)發(fā)TCP代理的實現(xiàn)示例
本文主要介紹了使用Nginx實現(xiàn)端口轉(zhuǎn)發(fā)TCP代理的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12
完美解決Nginx 504 Gateway time-out問題
這篇文章主要介紹了完美解決Nginx 504 Gateway time-out問題,需要的朋友可以參考下2014-11-11

