转载请备注来源: 《Nginx信号管理》 | shuwoom.com

本文摘要

这篇文章主要介绍Nginx信号管理方面的知识以及实践操作。通过这篇文章,我们会讲解Nginx的信号管理体系,以及Nginx信号管理的常见操作,包括Nginx reload流程(优雅重启配置)、Nginx热升级流程和Nginx日志切割。

Nginx命令行管理

Nginx的管理可以通过两种方式实现,一种是通过命令行,如下:

[root@VM_16_4_centos ~]# nginx -h
nginx version: nginx/1.14.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: /usr/local/services/nginx-1.0/)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

另一种就是今天我们要讲的—信号。

Nginx信号管理

Nginx的信号管理命令为:

kill -参数 Nginx进程号
例如:
kill -HUP $(cat /usr/local/nginx/logs/nginx.pid)

Nginx可用的信号如下表所示(参见官网):

TERM, INTQuick shutdown
QUITGraceful shutdown((优雅关闭进程,等请求结束后再关闭)
KILLHalts a stubborn process(强制关闭进程)
HUPConfiguration reloadStart the new worker processes with a new configurationGracefully shutdown the old worker processes(改变配置文件,平滑重读配置文件)
USR1Reopen the log files(重读日志,可以在日志切割时使用)
USR2Upgrade Executable on the fly(平滑升级)
WINCHGracefully shutdown the worker processes(优雅关闭旧的进程)

其与命令行参数的映射管下如下:

参数对应信号
reloadHUP
reopenUSR1
stopTERM
quitQUIT

下面我们说说几个比较重要的操作的流程。

Nginx reload(优雅重启配置)

nginx -s reload

或者使用信号:

kill -HUP nginx进程号

当我们发送上述信号时,其内部执行流程如下一节所示。

Nginx reload流程

  • 向master进程发送HUP信号(reload命令)
  • master进程校验配置语法是否正确
  • master进程打开新的监听端口
  • master进程用新配置启动新的worker紫禁城
  • master进程向老worker子进程发送QUIT信号
  • 老worker进程关闭监听句柄,处理完当前连接后结束进程

其示意图如下:

1563609553562

Nginx reload实践操作

reload前,nginx进程号如下:

[root@VM_16_4_centos sbin]# ps -ef|grep nginx
root     27112     1  0 15:52 ?        00:00:00 nginx: master process /usr/local/services/nginx-1.0/sbin/nginx -c /usr/local/services/nginx-1.0/conf/nginx.conf
nginx    27113 27112  0 15:52 ?        00:00:00 nginx: worker process
nginx    27114 27112  0 15:52 ?        00:00:00 nginx: worker process
nginx    27116 27112  0 15:52 ?        00:00:00 nginx: worker process
nginx    27117 27112  0 15:52 ?        00:00:00 nginx: worker process

我们修改配置执行reload命令后,nginx进程号可见发生了变化:

[root@VM_16_4_centos nginx-1.0]# sbin/nginx -s reload
[root@VM_16_4_centos nginx-1.0]# ps -ef|grep nginx
root     27112     1  0 15:52 ?        00:00:00 nginx: master process /usr/local/services/nginx-1.0/sbin/nginx -c /usr/local/services/nginx-1.0/conf/nginx.conf
nginx    27473 27112  0 15:53 ?        00:00:00 nginx: worker process
nginx    27474 27112  0 15:53 ?        00:00:00 nginx: worker process
nginx    27475 27112  0 15:53 ?        00:00:00 nginx: worker process
nginx    27476 27112  0 15:53 ?        00:00:00 nginx: worker process

Nginx热升级

Nginx热升级流程

  • 将旧的Nginx文件换成新Nginx文件(注意备份)
  • 向master进程发送USR2信号
  • master进程修改pid文件名,加后缀.oldbin
  • master进程用新Nginx文件启动新master进程
  • 向老master进程发送QUIT信号,关闭老master
  • 回滚:向老master发送HUP,向新master发送QUIT

Nginx热升级流程图如下:

1563611008319

Nginx热升级实践操作

  • 首先,我们将原nginx二进制文件做一份拷贝
  [root@VM_16_4_centos nginx]# ll /usr/local/services/nginx-1.0/sbin/
  total 11600
  -rwxr-xr-x 1 root root 5937128 Jun 14 13:13 nginx
  -rwxr-xr-x 1 root root 5937128 Jul 20 16:24 nginx.old
  • 然后我们将原nginx二进制文件替换成新的二进制文件,注意看文件时间:
  [root@VM_16_4_centos nginx]# ll /usr/local/services/nginx-1.0/sbin/
  total 11600
  -rwxr-xr-x 1 root root 5937128 Jul 20 16:26 nginx
  -rwxr-xr-x 1 root root 5937128 Jul 20 16:24 nginx.old
  • 然后向master进程发送USR2信号:
  [root@VM_16_4_centos nginx]# ps -ef|grep nginx |grep -v grep
  root     27112     1  0 15:52 ?        00:00:00 nginx: master process /usr/local/services/nginx-1.0/sbin/nginx -c /usr/local/services/nginx-1.0/conf/nginx.conf
  nginx    31901 27112  0 16:08 ?        00:00:00 nginx: worker process
  nginx    31902 27112  0 16:08 ?        00:00:00 nginx: worker process
  nginx    31903 27112  0 16:08 ?        00:00:00 nginx: worker process
  nginx    31904 27112  0 16:08 ?        00:00:00 nginx: worker process

  kill -USR2 27112

这时候我们再看nginx进程列表,可以看到,nginx进程数量多了一倍。8372master进程是基于新的nginx文件运行的,其下也创建了新的worker进程。

  root      8372 27112  0 16:28 ?        00:00:00 nginx: master process /usr/local/services/nginx-1.0/sbin/nginx -c /usr/local/services/nginx-1.0/conf/nginx.conf
  nginx     8373  8372  0 16:28 ?        00:00:00 nginx: worker process
  nginx     8374  8372  0 16:28 ?        00:00:00 nginx: worker process
  nginx     8375  8372  0 16:28 ?        00:00:00 nginx: worker process
  nginx     8376  8372  0 16:28 ?        00:00:00 nginx: worker process
  root     27112     1  0 15:52 ?        00:00:00 nginx: master process /usr/local/services/nginx-1.0/sbin/nginx -c /usr/local/services/nginx-1.0/conf/nginx.conf
  nginx    31901 27112  0 16:08 ?        00:00:00 nginx: worker process
  nginx    31902 27112  0 16:08 ?        00:00:00 nginx: worker process
  nginx    31903 27112  0 16:08 ?        00:00:00 nginx: worker process
  nginx    31904 27112  0 16:08 ?        00:00:00 nginx: worker process
  • 接下来,我们可以向老master进程发送QUIT信号,关闭老master,如下,我们可以看到老master和worker进程已经关闭,剩下新的master和worker进程。至此,我们就完成了nginx热升级过程。
[root@VM_16_4_centos nginx-1.0]# kill -QUIT 27112
[root@VM_16_4_centos nginx-1.0]# ps -ef|grep nginx
root      8372     1  0 16:28 ?        00:00:00 nginx: master process /usr/local/services/nginx-1.0/sbin/nginx -c /usr/local/services/nginx-1.0/conf/nginx.conf
nginx     8373  8372  0 16:28 ?        00:00:00 nginx: worker process
nginx     8374  8372  0 16:28 ?        00:00:00 nginx: worker process
nginx     8375  8372  0 16:28 ?        00:00:00 nginx: worker process
nginx     8376  8372  0 16:28 ?        00:00:00 nginx: worker process
root      9511 23269  0 16:32 pts/0    00:00:00 grep --color=auto nginx
  

Nginx日志切割

Nginx日志切割命令/信号

nginx -s reopen

或使用信号

kill - USR1 nginx进程id

Nginx日志切割实践操作

一开始日志目录下的文件如下:

-rw-r--r-- 1 nginx root 2371 Jul 20 16:09 access.log
-rw-r--r-- 1 nginx root 1613 Jul 18 08:47 error.log

接着将access重命名

mv access.log 1_access.log

使用日志重读命令:

[root@VM_16_4_centos nginx-1.0]# ps -ef|grep nginx
root     27112     1  0 15:52 ?        00:00:00 nginx: master process /usr/local/services/nginx-1.0/sbin/nginx -c /usr/local/services/nginx-1.0/conf/nginx.conf
nginx    31901 27112  0 16:08 ?        00:00:00 nginx: worker process
nginx    31902 27112  0 16:08 ?        00:00:00 nginx: worker process
nginx    31903 27112  0 16:08 ?        00:00:00 nginx: worker process
nginx    31904 27112  0 16:08 ?        00:00:00 nginx: worker process

kill -USR1 27112

这时候再重新看,就会有新的access.log文件生成:

[root@VM_16_4_centos nginx-1.0]# ll
total 20
-rw-r--r-- 1 nginx root 5687 Jul 20 16:10 1_access.log
-rw-r--r-- 1 nginx root 5320 Jul 20 16:12 access.log
-rw-r--r-- 1 nginx root 1613 Jul 18 08:47 error.log
  • 实践操作

在实际生产环境中,我们可以通过crontab的方式定时去切割脚本,例如脚本如下:

#!/bin/bash
v_logs_path="/usr/local/nginx/logs"
v_log_name="access.log"
v_pid_path="/usr/local/nginx/logs/nginx.pid"

mv ${v_logs_path}/${v_log_name} ${v_logs_path}/"access-"$(date --date="LAST DAY" "+%Y-%m-%d").log

kill -USR1 `cat ${v_pid_path}`

然后将crontab设为每天0点0分执行:

0 0 * * * sh /usr/local/nginx/logs/cut_nginx_log.sh &

转载请备注来源: 《Nginx信号管理》 | shuwoom.com

打赏

发表评论

电子邮件地址不会被公开。