Nginx 的热加载和热部署

摘要:nginx 的热加载和热部署,我们可以在不重启 nginx 的前提下,可以修改 nginx 配置文件,然后利用 reload 命令来热加载,也可以在不重启 nginx 的前提下,进行 nginx 的版本升级或者回退。

Nginx 的热加载

一般来讲,如果我们修改了配置文件,就需要把服务重新启动一下,让服务重新加载新的配置文件开始干活。但是 nginx 不用,他就可以在不关闭重启 nginx 服务的情况下重新加载配置文件干活。

具体步骤如下:

1、执行 nginx -s reload 命令向 master 发送终止信号。

2、master 进程校验配置语法是否正确。

3、master 进程打开新的监听端口。

4、master 进程用配置启动新的 worker 子进程(此时新老 worker 进程是并存的)。比如,启动 2 个 worker 进程,来接受新的请求。

5、master 进程向老的子进程发送 quit 信号来关闭老的 worker 进程。

6、老 worker 进程关闭监听句柄,处理完请求后自动关闭。但是有可能这个请求出问题,这个请求一直没有处理,就会一致占用这个 worker 进程。nginx 提供了一个配置叫  worker_shert_dump 来设置超过多久自动关闭这个 worker 进程。

比如下面这个操作,可以观察下重新加载配置文件后 master 进程的 pid 和 worker 进程的 pid,你会发现只有 worker 进程的 pid 变了,而 master 进程的 pid 并没有变,重新加载配置文件前和后都是 19569。如果 master 进程的 pid 变了,意味着 nginx 重启了,但是并没有。

[root@bogon ~]# ps aux | grep nginx                     
root     19569  0.0  0.1  16140  1372 ?        Ss   10月13   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody   38778  0.0  0.1  16560  1320 ?        S    19:28   0:00 nginx: worker process
nobody   38779  0.0  0.1  16560  1320 ?        S    19:28   0:00 nginx: worker process
root     38790  0.0  0.0 112728   964 pts/0    R+   19:40   0:00 grep --color=auto nginx
[root@bogon ~]# /usr/local/nginx/sbin/nginx -s reload   
[root@bogon ~]# ps aux | grep nginx                  
root     19569  0.0  0.1  16140  1372 ?        Ss   10月13   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody   38792  0.0  0.1  16560  1412 ?        S    19:40   0:00 nginx: worker process
nobody   38793  0.0  0.1  16560  1412 ?        S    19:40   0:00 nginx: worker process
root     38795  0.0  0.0 112728   960 pts/0    R+   19:40   0:00 grep --color=auto nginx


Nginx 的热部署

不用关闭 nginx 的服务,可以直接实现的 nginx 的升级和降级。比如当前版本版本是 nginx-1.14.2 我们在不重启的情况下将他升级成 nginx-1.16.1 版本。

涉及的命令如下

kill -USER2 进程号:不再让worker进程接受请求,当前请求处理完就让worker进程退出。

kill -WINCH 进程号:处理完关闭。

kill -HUP 进程号:启动进程。

演示步骤大致如下

1、当前运行的 nginx-1.14.2

[root@localhost ~]# ps -ef | grep nginx
root      2534     1  0 04:43 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    2535  2534  0 04:43 ?        00:00:00 nginx: worker process
root      2969  2953  0 06:58 pts/1    00:00:00 grep --color=auto nginx


2、下载安装 nginx-1.16.1 编译安装,但是不要执行 make install 命令。

[root@localhost ~]# wget http://nginx.org/download/nginx-1.16.1.tar.gz
[root@localhost ~]# ./configure --prefix=/usr/local/nginx --with-pcre=./pcre-8.42 --with-zlib=./zlib-1.2.11
[root@localhost ~]# make
[root@localhost ~]# cd nginx-1.16.1
[root@localhost nginx-1.16.1]# ll
总用量 780
drwxr-xr-x.  6 1001  1001   4096 10月 21 07:02 auto
-rw-r--r--.  1 1001  1001 296463 8月  13 20:51 CHANGES
-rw-r--r--.  1 1001  1001 452171 8月  13 20:51 CHANGES.ru
drwxr-xr-x.  2 1001  1001   4096 10月 21 07:02 conf
-rwxr-xr-x.  1 1001  1001   2502 8月  13 20:51 configure
drwxr-xr-x.  4 1001  1001     68 10月 21 07:02 contrib
drwxr-xr-x.  2 1001  1001     38 10月 21 07:02 html
-rw-r--r--.  1 1001  1001   1397 8月  13 20:51 LICENSE
-rw-r--r--.  1 root root     376 10月 21 07:02 Makefile
drwxr-xr-x.  2 1001  1001     20 10月 21 07:02 man
drwxr-xr-x.  3 root root    4096 10月 21 07:03 objs
drwxr-xr-x.  9 1169  1169   8192 10月 21 07:03 pcre-8.42
-rw-r--r--.  1 1001  1001     49 8月  13 20:51 README
drwxr-xr-x.  9 1001  1001     84 10月 21 07:02 src
drwxr-xr-x. 14  501 games   4096 10月 21 07:03 zlib-1.2.11


3、备份 nginx-1.14.2 版本的 nginx 二进制文件,我们只会更换 nginx 的二进制文件,不需要更换其他文件。

[root@localhost sbin]# pwd
/usr/local/nginx/sbin
[root@localhost sbin]# cp nginx nginx.old
[root@localhost sbin]# ll
总用量 7576
-rwxr-xr-x. 1 root root 3878236 10月 17 06:53 nginx
-rwxr-xr-x. 1 root root 3878236 10月 21 07:05 nginx.old


4、迁移 nginx-1.16.1 版本的 nginx 二进制文件,迁移过程中需要加 -f 参数,否则会报一个文在正在执行中无法覆盖的错误,迁移后通过文件大小的对比,现在二进制文件是 nginx-1.16.1 版本的。

[root@localhost objs]# pwd
/root/nginx-1.16.1/objs
[root@localhost objs]# cp nginx /usr/local/nginx/sbin/nginx
cp:是否覆盖"/usr/local/nginx/sbin/nginx"? y
cp: 无法创建普通文件"/usr/local/nginx/sbin/nginx": 文本文件忙
[root@localhost objs]# cp -f nginx /usr/local/nginx/sbin/nginx
cp:是否覆盖"/usr/local/nginx/sbin/nginx"? y
[root@localhost sbin]# ll
总用量 7656
-rwxr-xr-x. 1 root root 3957003 10月 21 07:15 nginx
-rwxr-xr-x. 1 root root 3878236 10月 21 07:05 nginx.old

我们可以测试下 nginx 服务,迁移完成后并不影响 nginx 的运行,看起来一切都是正常的,通过返回的 header 头信息显示,现在运行的还是 nginx-1.14.2 版本。

[root@localhost sbin]# ps -ef | grep nginx
root      2534     1  0 04:43 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    2535  2534  0 04:43 ?        00:00:00 nginx: worker process
root      9312  2953  0 07:18 pts/1    00:00:00 grep --color=auto nginx
[root@localhost sbin]# curl -I 192.168.242.131
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Sun, 20 Oct 2019 23:31:05 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 16 Oct 2019 22:53:37 GMT
Connection: keep-alive
ETag: "5da79f71-264"
Accept-Ranges: bytes


5、使用 kill -USR2 PID 命令向 nginx-1.14.2 发送信号,我们要平滑升级了。

[root@localhost sbin]# ps -ef | grep nginx
root      2534     1  0 04:43 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    2535  2534  0 04:43 ?        00:00:00 nginx: worker process
root      9315  2953  0 07:21 pts/1    00:00:00 grep --color=auto nginx
[root@localhost sbin]# kill -USR2 2534

可以看到 nginx 的 master 进程新启了一个进程号为 9316 的 master 进程,这个新的 master 进程是由 nginx-1.16.1 复制过来的二进制文件启动的,还可以看出来新的 master 进程的 ppid 是老 master 进程的 pid。

老的 worker 进程也在工作,新的 master 会生成新的 worker 进程,它们会把新的请求平滑的过渡到用新的二进制文件启动的进程中。现在我们再次访问 nginx 服务,可以看到现在是 nginx-1.16.1 版本。

[root@localhost sbin]# ps -ef | grep nginx
root      2534     1  0 04:43 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    2535  2534  0 04:43 ?        00:00:00 nginx: worker process
root      9316  2534  0 07:21 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    9317  9316  0 07:21 ?        00:00:00 nginx: worker process
root      9319  2953  0 07:21 pts/1    00:00:00 grep --color=auto nginx
[root@localhost sbin]# curl -I 192.168.242.131
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Sun, 20 Oct 2019 23:31:05 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 16 Oct 2019 22:53:37 GMT
Connection: keep-alive
ETag: "5da79f71-264"
Accept-Ranges: bytes

然新老 master 和 worker 都在运行,但是老的进程已经不再监听 80 或者 443 端口了,所有的请求已经交给新的进程了。


6、向老的 nginx-1.14.2 进程发送信号,请优雅的关闭你的所有的 worker 进程。

[root@localhost sbin]# kill -WINCH 2534
[root@localhost sbin]# ps -ef | grep nginx
root      2534     1  0 04:43 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
root      9316  2534  0 07:21 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    9317  9316  0 07:21 ?        00:00:00 nginx: worker process
root      9366  2953  0 07:41 pts/1    00:00:00 grep --color=auto nginx

虽然老的 worker 进程已经关闭了,但是老的 master 进程还在,这样有一个好处,就是如果新的版本出现了问题,我们可以版本回退,让老的 master 进程重新把 worker 进程拉起来接受请求。


7、版本回退,可以看到一波操作后,我们现在访问 nginx 服务又回退到 nginx-1.14.2 版本了。

[root@localhost sbin]# kill -HUP 2534
[root@localhost sbin]# ps -ef | grep nginx
root      2534     1  0 04:43 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
root      9316  2534  0 07:21 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    9372  9316  0 07:47 ?        00:00:00 nginx: worker process
nobody    9380  2534  0 07:49 ?        00:00:00 nginx: worker process
root      9382  2953  0 07:49 pts/1    00:00:00 grep --color=auto nginx
[root@localhost sbin]# kill -WINCH 9316
[root@localhost sbin]# ps -ef | grep nginx
root      2534     1  0 04:43 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
root      9316  2534  0 07:21 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody    9380  2534  0 07:49 ?        00:00:00 nginx: worker process
root      9385  2953  0 07:49 pts/1    00:00:00 grep --color=auto nginx
[root@localhost sbin]# curl -I 192.168.242.131
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Sun, 20 Oct 2019 23:50:04 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 16 Oct 2019 22:53:37 GMT
Connection: keep-alive
ETag: "5da79f71-264"
Accept-Ranges: bytes
结束语:感谢您对本网站文章的浏览,欢迎您的分享和转载,但转载请说明文章出处。
Top