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);
});
});

[原创] Nginx1.13版本reload过程对TCP包影响的测试的更多相关文章

  1. centos7安装nginx-1.13.6 新手入门,图文解析

    系统环境 操作系统:64位CentOS Linux release 7.2.1511 (Core) 安装nginx依赖包 [root@localhost ~]# yum install gcc-c++ ...

  2. CentOS7 + Nginx1.13.5 + PHP7.1.10 + MySQL5.7.19 源码编译安装

    一.安装Nginx 1.安装依赖扩展 # yum -y install wget openssl* gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng ...

  3. [转帖]IP /TCP协议及握手过程和数据包格式中级详解

    IP /TCP协议及握手过程和数据包格式中级详解 https://www.toutiao.com/a6665292902458982926/ 写的挺好的 其实 一直没闹明白 网络好 广播地址 还有 网 ...

  4. CentOS 7配置nginx-1.13.10支持http/2和Server Push

    0.确保openssl版本大于1.0.2 openssl version 1.下载nginx-1.13.10 wget http://nginx.org/download/nginx-1.13.10. ...

  5. CentOS下 Nginx1.13.5 + PHP7.1.10 + MySQL5.7.19 源码编译安装

    一.安装Nginx ①安装依赖扩展 # yum -y install wget openssl* gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng l ...

  6. 《k8s-1.13版本源码分析》-测试环境搭建(k8s-1.13版本单节点环境搭建)

    本文原始地址(gitbook格式):https://farmer-hutao.github.io/k8s-source-code-analysis/prepare/debug-environment. ...

  7. CentOS 7 Nginx1.12.2平滑升级到新版本nginx-1.13.3

    查看当前Nginx版本信息 [root@web ~]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/ built by gcc (Red H ...

  8. windows10下 MySQL5.7.18版本安装过程及遇到的问题

    windows10下 MySQL5.7.18版本安装过程及遇到的问题           mysql-5.7.18-winx64 安装           1.解压 此次将MySQL装在H盘,依个人喜 ...

  9. Centos7 下nginx nginx-1.13.4 安装

    环境:CentOS Linux release 7.3.1611 (Core)  Linux localhost.localdomain 3.10.0-514.26.2.el7.x86_64 #1 S ...

随机推荐

  1. C#2.0新增功能03 匿名方法

    连载目录    [已更新最新开发文章,点击查看详细] 在 2.0 之前的 C# 版本中,声明委托的唯一方式是使用命名方法. C# 2.0 引入匿名方法,在 C# 3.0 及更高版本中,Lambda 表 ...

  2. C-哈夫曼编码

    /*author:windy_2*/ /*修正版*/ #include<stdio.h> #include<stdlib.h> #include<string.h> ...

  3. C#中线程间操作无效: 从不是创建控件 txtBOX 的线程访问它。

    delegate void 委托名(方法名); void 方法名() { if(txtBox.invokeRequered) { 委托名 d=new 委托名(); txtBox.invoke(d); ...

  4. .Net微信网页开发之使用微信JS-SDK调用微信扫一扫功能

    前言: 之前有个项目需要调用微信扫描二维码的功能,通过调用微信扫码二维码功能,然后去获取到系统中生成的二维码信息.正好微信JS-SDK提供了调用微信扫一扫的功能接口,下面让我们来看看是如何实现的吧. ...

  5. husky+ prettier + commitlint 提交前代码检查和提交信息规范

    一.安装相关的包 npm install -D husky npm install -D lint-staged // lint钩子 npm install -D prettiernpm instal ...

  6. Could not link: /usr/local/etc/bash_completion.d/brew

    用终端 brew update 或 brew install ** 时遇到的问题,详细如下: Error: Could not link: /usr/local/etc/bash_completion ...

  7. JDBC连接池-C3P0连接

    JDBC连接池-C3P0连接 c3p0连接池的学习英语好的看英文原版      c3p0 - JDBC3 Connection and Statement Pooling 使用c3p0连接池  三种方 ...

  8. 使用用树莓派打造远程WEB服务器

    简介:系统配置Raspberry Pi 3B + Raspbian + MySQL5.7 + Tomcat 9 + Nginx + 公网IP. 工具:Win32DiskImager .FileZill ...

  9. 一个项目的SpringCloud微服务改造过程

    SSO是公司一个已经存在了若干年的项目,后端采用SpringMVC.MyBatis,数据库使用MySQL,前端展示使用Freemark.今年,我们对该项目进行了一次革命性的改进,改造成SpringCl ...

  10. JavaScript数据结构——字典和散列表的实现

    在前一篇文章中,我们介绍了如何在JavaScript中实现集合.字典和集合的主要区别就在于,集合中数据是以[值,值]的形式保存的,我们只关心值本身:而在字典和散列表中数据是以[键,值]的形式保存的,键 ...