[原創] Nginx1.13版本reload過程對TCP包影響的測試


Nginx1.13版本reload過程中各項連接情況和狀態的測試。測試Nginx1.13 Reload過程中,對客戶端和服務器的TCP層面的包影響。
    1)對客戶端開啟長連接,服務端開啟/不開啟長連接情況下
        測試方法:瀏覽器發起http自帶connection:keep-alive,服務端分別在開啟和不開啟長連接的情況下,然后在重新打開瀏覽器訪問,連續訪問5次,期間會reload nginx。整個過程對81和8010端口抓包。
    2)對TCP長連接代理的情況下
        測試方法:連接82端口,發送tcp,再發送tcp1,斷開連接。然后連接ws,發送tcp_reload,執行nginx reload,再發送tcp_reload1,斷開連接。整個過程抓82和8012端口的包。
    3)對Websocket保持連接的情況下
        測試方法:連接ws,發送hello,再發送hello1,斷開連接。然后連接ws,發送hello_reload,執行nginx reload,再發送hello_reload1,斷開連接。整個過程抓81和8010端口的包。
 
如下所示,是測試的環境訪問流程。三項測試都是用該環境。
 
** 測試代碼見文章末尾
 
1)對客戶端開啟長連接,服務端開啟/不開啟長連接情況下
1.1)環境的配置:
Real server使用python的SimpleHTTPServer模塊啟動一個簡單的web服務,監聽8010端口。如下圖所示:
 

 

 

1.2)Nginx的配置:
不開啟長連接時的配置如下,開啟長連接時把注釋去掉即可:
upstream websocket {
    server localhost:8010;
    #keepalive 2;
}
 
server {
    listen 81;
    server_name localhost;
 
    location /websocket {
        proxy_pass http://websocket/;
        #proxy_http_version 1.1;
        #proxy_set_header Connection "";
}
 
1.3)測試方法:瀏覽器發起http自帶connection:keep-alive,服務端分別在開啟和不開啟長連接的情況下,然后在重新打開瀏覽器訪問,連續訪問5次,期間會reload nginx。整個過程對81和8010端口抓包。
81端口的抓包情況如下:
開啟長連接時8010端口的抓包情況如下:
 
發現開啟了長連接之后每次請求都會新建連接,進行三次握手,這是因為SimpleHTTPServer沒有做處理的原因,換成tomcat(8080端口)之后,同樣配置下訪問五次使用的是同一個連接進行傳輸的。如下所示:

 

 

不開啟長連接時8010端口的抓包情況如下:

 

 

2)對TCP長連接代理的情況下
2.1)環境的配置:
Real server使用python實現TCP Server,監聽8012端口。如下圖所示:

 

 

客戶端使用python實現TCP Client。連接nginx的82端口。如下圖所示:
 
2.2)Nginx的配置:
tcp代理的配置如下:
stream {
    upstream tcp_server {
        server localhost:8012 weight=5;
    }
    server {
        listen 82;
        proxy_responses 1;
        proxy_timeout 20s;
        proxy_pass tcp_server;
    }
}

 

2.3)測試方法:連接82端口,發送tcp,再發送tcp1,斷開連接。然后連接ws,發送tcp_reload,執行nginx reload,再發送tcp_reload1,斷開連接。整個過程抓82和8012端口的包。
82端口抓到的包如下:
 
8012端口抓到的包如下:
 
2.4)nginx reload前后進程狀態對比:
 
3)對Websocket保持連接的情況下
3.1)環境的配置:
Real server使用nodejs的啟動一個簡單的websocket服務,監聽8010端口。如下圖所示:
 
客戶端連接如下:

 

 

3.2)Nginx的配置:
不開啟長連接時的配置如下,開啟長連接時把map段和proxy_set_header注釋即可:
upstream websocket {
    server localhost:8010;
    #keepalive 2;
}
 
server {
    listen 81;
    server_name localhost;
 
    location /websocket {
        proxy_pass http://websocket/;
        #proxy_http_version 1.1;
        #proxy_set_header Connection "";
}
 
3.3)測試方法:連接ws,發送hello,再發送hello1,斷開連接。然后連接ws,發送hello_reload,執行nginx reload,再發送hello_reload1,斷開連接。整個過程抓81和8010端口的包。
81端口抓到的包如下:
 

 

 

8010端口抓到的包如下:

 

 

3.4)nginx reload前后進程狀態對比:
 
 
結論:綜上分析可知,不管nginx是否開啟長連接,nginx在reload過程中,nginx對客戶端和反向代理的后端在TCP代理,websocket代理和upstream反向代理的情況下均沒有影響,nginx會在reload時把正常處理連接的worker設置shutting down狀態,不接受新的請求,然后新啟動一個worker進程接收處理新的請求,shutting down的worker直至處理完當前連接之后優雅退出。對於客戶端的連接也是一樣的。
 
# cat tcp_server.py
# -*- coding: utf-8 -*-

import SocketServer
from SocketServer import StreamRequestHandler as SRH
from time import ctime
import time

import sys
reload(sys)
sys.setdefaultencoding('utf8')

#host = '127.0.0.1'
host='127.0.0.1'
port = 8012
addr = (host, port)


class Servers(SRH):
    def handle(self):
        print 'got connection from ', self.client_address
        self.wfile.write('connection %s:%s at %s succeed!' % (host, port, ctime()))
        while True:
            data = self.request.recv(1024)
            if not data:
                break
            #print data
            cur_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            print "%s RECV from %s, data is:%s" % (cur_time,self.client_address[0],data)
            self.request.send(data)


print 'server is running....'
server = SocketServer.ThreadingTCPServer(addr, Servers)
server.serve_forever()

 

# cat server.js
console.log("Server started");
var Msg = '';
var WebSocketServer = require('ws').Server
    , wss = new WebSocketServer({port: 8010});
    wss.on('connection', function(ws) {
        ws.on('message', function(message) {
        console.log('Received from client: %s', message);
        ws.send('Server received from client: ' + message);
    });
 });

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM