[code.nginx] Nginx启动、停止、重启

Nginx服务的信号控制

在Nginx服务的启动停止等方式中,有一种是通过信号机制来实现的。Nginx服务在运行时,会保持一个主进程和一个或多个worker process工作进程。通过给nginx的主进程发送信号就可以控制服务的启动停止了,在发送信号之前首先要知道主进程的进程号PID。
获取PID有两个途径:

  1. 在Nginx服务启动以后,默认在Nginx服务器安装目录下的logs目录中会产生名为nginx.pid的文件,此文件中保持的就是Nginx服务主进程的PID。这个文件的存放路径和文件名都可以在Nginx服务器的配置文件中进行配置。
  2. 获取Nginx服务主进程PID的办法是使用Linux平台下查看进程的工具ps,使用方法是:
Jorys-MBP:logs jory$ ps -ef | grep nginx
    0    56     1   0  2:51PM ??         0:00.02 nginx: master process /usr/local/opt/nginx/bin/nginx -g daemon off;  
   -2   225    56   0  2:51PM ??         0:00.00 nginx: worker process  
  501  3680  3482   0 10:33PM ttys000    0:00.00 grep nginx

从命令结果来看系统中包含Nginx服务的主进程master process和三个工作进程worker process,其中主进程对应的PID为第二列中的56,这和nginx.pid文件中的一致。

Jorys-MBP:nginx jory$ cat /usr/local/var/run/nginx.pid
56

Nginx服务主进程能够接收的信号如下表所示。

信号 作用
TERM或INT 快速停止Nginx服务
QUIT 平缓停止Nginx服务
HUP 使用新的配置文件启动进程,之后平缓停止原有进程,也就是所谓的“平滑重启”
USR1 重新打开日志文件,常用于日志切割
USR2 使用新版本的Nginx文件启动服务,之后平缓停止原有Nginx进程,也就是所谓的“平滑升级”
WINCH 平缓停止worker process,用于Nginx服务器平滑升级

向Nginx服务主进程发送信号也有两种方法。一种是使用nginx二进制文件,另一种方法是是用kill命令发送信号。其用法是:

kill SIGNAL PID

SIGNAL,用于指定信号,即指定上表中的某一个。
PID,指定Nginx服务主进程的PID,也可以使用nginx.pid动态获取PID号:

kill SIGNAL 'filepath'

其中,filepath为nginx.pid的路径。

Nginx服务的启动

在Linux平台下,启动Nginx服务器直接运行安装目录下sbin目录中的二进制文件即可。下面简要介绍一下二进制文件nginx的相关用法。运行下面命令:

Jorys-MBP:nginx jory$ nginx -h
nginx version: nginx/1.12.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/Cellar/nginx/1.12.0/)
  -c filename   : set configuration file (default: /usr/local/etc/nginx/nginx.conf)
  -g directives : set global directives out of configuration file

下面逐条分析帮助信息里允许使用的参数:

  • “-h”或者“-?”用来打印二进制文件的nginx的用法,也就是当前显示的内容。
  • “-v”用来显示Nginx服务器的版本号
  • “-V”除了显示版本号,还显示Nginx服务器编译情况,如下所示:
Jorys-MBP:nginx jory$ nginx -V
nginx version: nginx/1.12.0
built by clang 8.1.0 (clang-802.0.42)
built with OpenSSL 1.1.0e  16 Feb 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/nginx/1.12.0 --with-http_ssl_module --with-pcre --sbin-path=/usr/local/Cellar/nginx/1.12.0/bin/nginx --with-cc-opt='-I/usr/local/opt/pcre/include -I/usr/local/opt/openssl@1.1/include' --with-ld-opt='-L/usr/local/opt/pcre/lib -L/usr/local/opt/openssl@1.1/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-http_gzip_static_module --with-ipv6
  • “-t”检查Nginx服务器配置文件是否有语法错误,可以与“-c”联用,使输出内容更详细,这对查找配置文件中的语法错误很有帮助,如果检查通过,将显示类似下面的信息:
Jorys-MBP:nginx jory$ nginx -t
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
  • “-q”与“-t”联用,如果配置文件无错误,将不输出上面的内容
  • “-s signal”用来向Nginx服务的主进程发送信号
  • “-p prefix”用来改变Nginx的安装路径,常用在平滑升级Nginx服务器的场合
  • “-c filename”用来指定启动Nginx服务使用的配置文件
  • “-g directives”用来补充Nginx配置文件,向Nginx服务指定启动时应用于全局的配置。

如果使用默认的配置文件,可以直接运行nginx

   sudo ./nginx

如果没有任何错误信息输出,Nginx服务就启动了。可以使用ps -ef | grep nginx命令查看Nginx服务的进程状态。

Nginx服务的停止

停止Nginx服务有两种方法:一种是快速停止,一种是平缓停止。快速停止是指立即停止当前Nginx服务正在处理的所有网络请求,马上丢弃连接,停止工作。平缓停止是指允许Nginx服务将当前正在处理的网络请求处理完成,但不再接收新的请求,之后关闭连接,停止工作。
停止Nginx服务的操作比较多。

  • nginx从容停止命令,等所有请求结束后关闭服务。
ps -ef |grep nginx
kill -QUIT  nginx主进程号
  • nginx 快速停止命令,立刻关闭nginx进程。
ps -ef |grep nginx
kill -TERM nginx主进程号 
  • 如果以上命令不管用,可以强制停止。
kill -9 nginx主进程号
  • 如果嫌麻烦可以不用查看进程号,直接使用命令进行操作。
    其中/usr/local/var/run/nginx.pid 为nginx.conf中pid命令设置的参数,用来存放nginx主进程号的文件。
kill -信号类型(HUP|TERM|QUIT) cat /usr/local/var/run/nginx.pid 
例如
kill -QUIT `cat /usr/local/var/run/nginx.pid`

Nginx服务的重启

更改Nginx服务器的配置和加入新模块后,如果希望当前Nginx服务应用新的配置或使新模块生效,就需要重启Nginx服务。当然我们可以先关闭Nginx服务,然后使用新的Nginx配置文件重启服务。
Nginx的平滑重启是这样一个过程,Nginx服务进程接收到信号后,首先读取新的Nginx配置文件,如果配置语法正确,则启动新的Nginx服务,然后平缓关闭旧的服务进程。如果新的Nginx配置有问题,将显示错误,仍然使用旧的Nginx进程提供服务。

如果改变了Nginx的配置文件(nginx.conf),想重启Nginx,可以发送系统信号给Nginx主进程的方式来进行。不过,在重启之前,要确认Nginx配置文件的语法是正确的,可通过如下命令测试配置文件是否正确:

Jorys-MBP:bin jory$ sudo nginx -t -c /usr/local/etc/nginx/nginx.conf
Password:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

如果配置文件不正确,屏幕会提示配置文件的第几行出错。
如果配置文件正确,屏幕将提示正确信息。
这时候,就可以平滑重启了。

对于Nginx 0.8.x之前的版本,可以使用:

kill -HUP `cat /usr/local/var/run/nginx.pid`

HUP信号用于发送平滑重启信号。

对于Nginx 0.8.x之后的版本,可以使用:

sudo nginx -s reload

Nginx服务器的升级

如果要对当前的Nginx服务器进行版本升级,应用新模块,最简单的办法是停止当前Nginx服务,然后开启新的Nginx服务,但这样就会导致在一段时间内,用户无法访问服务器。为了解决这个问题,Nginx服务器提供平滑升级的功能。
平滑升级的过程是这样的,Nginx服务接收到USER2信号后,首先将旧的nginx.pid文件(如果在配置文件中更改过这个文件的名字,也是相同的过程)添加后缀.oldbin,变为nginx.pid.oldbin文件。然后执行新版本Nginx服务器的二进制文件启动服务。如果新的服务器启动成功,系统中将有新旧两个Nginx服务共同提供Web服务。之后,需要向旧的Nginx服务进程放WINCH信号,使旧的Nginx服务平滑停止,并删除nginx.pid.oldbin文件。在发送WINCH信号之前,可以随时停止新的Nginx服务。

为了实现Nginx服务器的平滑升级,新的服务器安装路径应该和旧的保持一致。因此建议用户在安装新服务器之前先备份旧服务器。如果由于某种原因无法保持新旧服务器安装路径一致,则可以先使用以下命令将旧服务器的安装路径更改为新服务器的安装路径:

 nginx -p newInstallPath

其中,newInstallPath为新服务器的安装路径。之后,备份旧服务器,安装新服务器即可。

当需要将正运行的Nginx升级,可以在不中断服务的情况下进行,具体步骤如下:

  1. 使用新的可执行程序替换旧的可执行程序。下载新的Nginx,重新编译到旧版本的安装路径中。重编译之前,先备份一下旧的可执行文件。
  2. 执行以下指令,他将存储有旧版本主进程ID的文件重命名为.oldbin:
kill -USR2 旧版本的Nginx主进程号
一般情况下是这样的:kill -USR2 `cat /usr/local/nginx/nginx.pid`

可以用 ls /usr/local/nginx/logs来查看是否改名

  1. 执行新版本的Nginx可执行程序。
ulimit -SHn 65535
/usr/local/nginx/sbin/nginx
  1. 此时新旧版本的Nginx会同时运行,共同处理请求。要逐步停止旧版本的Nginx,必须发送WINCH信号给旧的主进程。然后,他的工作进程将从容关闭。
kill -WINCH 旧版本的Nginx主进程号
  1. 一段时间后,旧的工作进程处理完了所有的请求后退出,仅由新的进程来处理输入请求了。可用下面的命令查看:
ps -ef | grep nginx
  1. 现在可以决定使用新版本还是恢复到旧版本:
    kill -HUP 旧的主进程号 :Nginx在不重载配置文件的情况下启动他的工作进程
    kill -QUIT 新的主进程号 :从容关闭其工作进程
    kill -TERM 新的主进程号 :强制退出
    kill 新的主进程号或旧的主进程号:如果因为某些原因新的工作进程不能退出,则向其发送kill信号

新的主进程退出后,旧的主进程会移除.oldbin后缀,恢复为他的.pid文件,这样,一切就都恢复为升级之前了。
如果尝试升级成功,而自己又希望保留新版本时,可发送QUIT信号给旧的主进程,使其退出而只留下新的进程运行:kill -QUIT 旧主进程号。
这样就在不停止提供Web服务的前提下完成了Nginx服务器的平滑升级。

推荐阅读更多精彩内容