• [原创] 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);
        });
     });
    

  • 相关阅读:
    string类型版本号比较
    地图
    使用libcurl显示下载进度
    欧几里德&扩展以及求解线性方程学习总结--附上poj1061解题报告
    [置顶] 两台一级域名相同二级域名不同的服务器,怎么共享session
    [源码分享] HIVE表数据量统计&邮件
    Domino 迁移到Exchange 服务器 之在Domino Server 创建用户!
    Lotus 迁移到Exchange POC 之 新建2007 服务器!
    uva 10056
    Lotus 迁移到Exchange 2010 POC 之在Exchange 2007安装Transport Suite!
  • 原文地址:https://www.cnblogs.com/wsjhk/p/11430613.html
Copyright © 2020-2023  润新知