[TOC] #### 1. 前言 --- nginx 安装后,接下来我们就要学习如何启动、停止、重启 nginx 的服务 对于 nginx 服务的启停控制,在 linux 系统中也有多种方式,比如:信号控制、命令行控制 信号控制:使用 nginx 服务的信号来控制,这种方式里面涉及到一些信号,重点是理解这些信号所代表的含义 命令行控制:使用 sbin 目录下的 nginx 可执行的二进制文件来控制,这种方式日常开发中使用的比较多,非常重要 #### 2. 信号控制 --- 信号控制:只需要给 master 进程发送信号就可以来控制 nginx,在学习日志分割、服务升级时会用到信号控制这种方式 想要操作 nginx 的 master 进程,就需要获取到 master 进程的进程 ID(PID) ##### a. 查看主进程 ID **方式一:运行以下命令查看 nginx 进程** ```bash ps -ef | grep nginx ``` ![](https://img.itqaq.com/art/content/bf81911fad5dcb2d25a14f6d51dd9a0c.png) **方式二:通过 nginx.pid 文件查看 master 进程 PID** 在使用 `./configure` 命令预编译时,有两个参数 `--prefix=PATH` 用于指定 nginx 安装目录,`--pid-path=PATH` 用于指定 nginx 主进程 IP 存放位置,默认存放位置是 nginx 安装目录下的 `logs/nginx.pid` 文件中 运行以下命令查看 nginx 安装信息 ```bash /usr/local/nginx/sbin/nginx -V ``` 发现安装目录为 `/usr/local/nginx`,未指定 pid 存放目录,则主进程 ID 存放位置为 `/usr/local/nginx/logs/nginx.pid` ![](https://img.itqaq.com/art/content/8c29e11700a802459642f4a3c2625533.png) 运行以下命令查看文件内容,也就是 nginx 的 master 进程 ID ```bash cat /usr/local/nginx/logs/nginx.pid ``` ![](https://img.itqaq.com/art/content/b8fee1b50494f934071fa88165c98f62.png) ##### b. 信号控制用法 获取到 nginx 的主进程 ID 之后,能干什么 | 信号 | 作用 | 等同于 | | ------------ | ------------ | ------------ | | TERM/INT | 立即关闭整个服务 | nginx -s stop | | QUIT | "优雅" 的关闭整个服务,worker 进程处理完当前用户请求再关闭 | nginx -s quit | | HUP | 重读配置文件并使用服务对新配置项生效 | nginx -s reload | | USR1 | 重新打开日志文件,可以用来进行日志切割 | nginx -s reopen | | USR2 | 平滑升级到最新版的 nginx | - | | WINCH | 所有子进程不在接收处理新连接,相当于给 worker 进程发送 QUIT 指令 | - | 调用命令: ```bash # signal:信号 # PID:nginx 的 master 线程 ID kill -[signal] PID ``` 使用示例: ```bash # TERM:立即关闭 nginx 服务,1294 是 master 进程 ID kill -TERM 1294 # QUIT:优雅的关闭 nginx 服务,1294 是 master 进程 ID kill -QUIT 1294 ``` 也可以使用下面这种写法,将 master 进程的 ID 改为命令输出结果,就不需要查看进程 ID 值了 ```bash kill -TERM `cat /usr/local/nginx/logs/nginx.pid` ``` USR1 信号:发送该信号给 master 进程,告诉 nginx 重新开启日志文件 ```bash # 删除日志文件 rm -rf /usr/local/nginx/logs/access.log /usr/local/nginx/logs/error.log # 运行以下命令会重新创建 access.log、error.log kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` ``` USR2信号:告诉 master 进程要平滑升级,将 nginx 从低版本升级到高版本,无需重启 nginx 服务,不影响用户访问 ![](https://img.itqaq.com/art/content/c6b0a115e6b03ec4bd6fca383038bee7.png) 通过这两步操作之后,运行在服务器上的就是最新开启的 master 进程,具体怎么实现我们通过实例看下效果 给 master 进程发送 USR2 信号,可以看到打开了一份新的 master、worker 进程 ```bash kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` ``` ![](https://img.itqaq.com/art/content/6219df83518744e07556224bd469a145.png) 如下图所示,USR2 信号会生成 `nginx.pid.oldbin` 文件,用于记录旧的 master 进程 ID ![](https://img.itqaq.com/art/content/f6eef15a90bc58975c2fa916bca82591.png) 假设我们确保 nginx 服务器已经升级成功,接下来运行以下命令 它的作用是等待旧的 worker 进程处理完用户请求后,将旧的 worker 进程和 master 进程都关闭掉 ```bash kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin` ``` 执行完命令之后,就可以发现只剩下新的 master、worker 进程 ![](https://img.itqaq.com/art/content/4bcd9cbd4c86fd562331d438165f8a42.png) WINCH 信号:所有子进程不在接收处理新连接,只关闭 woker 进程,不关闭 master 进程 ```bash kill -WINCH `cat /usr/local/nginx/logs/nginx.pid` ``` ![](https://img.itqaq.com/art/content/ee548e3af8f9a9af5e934dc331385ddc.png) **QUIT 信号 和 WINCH 信号的区别?** 都是等 worker 进程处理完当前用户请求再将 worker 进程关闭掉,WINCH 信号到此就结束了,而不会关闭 master 进程,但是 QUIT 信号会将 master 进程也关闭掉 #### 3. 命令行控制 --- 命令行控制:这种方式是使用 sbin 目录下的 nginx 可执行的二进制文件来进行 nginx 状态的控制 执行二进制文件的写法示例 ```bash # 相对路径 cd /usr/local/nginx/sbin ./nginx -s reload # 绝对路径 /usr/local/nginx/sbin/nginx -s reload # 定义了环境变量或命令别名 nginx -s reload ``` 运行以下命令查看都有哪些参数可用 ```bash nginx -h ``` | 参数 | 描述 | | ------------ | ------------ | | -? 和 -h | 显示帮助信息 | | -v | 查看 nginx 版本号 | | -V | 查看 nginx 版本号和配置信息 | | -t | 测试配置文件语法是否正确 | | -T | 测试配置文件语法是否正确,并输出用到的配置文件 | | -q | 配置测试期间不显示非错误消息 | | -p | 指定 nginx 的 prefix 路径,默认为:/usr/local/nginx | | -c | 指定 nginx 的 配置文件路径,默认为:conf/nginx.conf | | -g | 用于补充 nginx 配置,向 nginx 服务指定启动时应用全局的配置 | ![](https://img.itqaq.com/art/content/4ddf7d64c7453147d8b04f6bdb3a856c.png) ##### -h ```bash # 下面两个命令作用是一样的 nginx -? nginx -h ``` ##### -v ```bash # 查看版本号 nginx -v # 查看版本号和配置信息 nginx -V ``` ![](https://img.itqaq.com/art/content/0e2c3eb8d651fc6cd6c430db4b08786e.png) ##### -q ```bash # 检测配置文件语法,运行命令可以看到没有错误信息,是正常的提示 nginx -t # 因为没有错误信息,所以什么也没有输出(不显示非错误信息) nginx -tq ``` ![](https://img.itqaq.com/art/content/70d3b29a61d148353b202df04854965b.png) 当有错误信息时,才会输出内容 ![](https://img.itqaq.com/art/content/270d291f611520c20b1581e316842195.png) ##### -s 给 master 进程发送信号控制 nginx 的状态,可用的信号:stop, quit, reopen, reload ```bash # 快速关闭,类似于 TERM/INT 信号的作用,直接关闭 master、worker 进程 nginx -s stop # 优雅关闭,类似于 QUIT 信号的作用,等待 worker 进程处理完请求再关闭 master、worker 进程 nginx -s quit # 重新打开日志文件,类似于 USR1 信号的作用 nginx -s reopen # 重载配置文件,类似于 HUP 信号的作用 nginx -s reload ``` ##### -c `-c` 参数用于指定 nginx 使用的配置文件,默认使用的是 nginx 安装目录下的 `conf/nginx.conf` 接下来,我们看下具体效果 首先,我们使用默认的 nginx.conf 创建出一个新的配置文件,用于测试使用 ```bash # 拷贝 nginx.conf 得到新的配置文件 abc.conf cp /usr/local/nginx/conf/nginx.conf /usr/local/abc.conf ``` 为了区分两个配置文件,我们修改一下 abc.conf,故意造成语法错误 ![](https://img.itqaq.com/art/content/a45fe4ba7393dac2bdd69196ed40f0c1.png) 运行以下命令进行语法检测,查看命令输出就可以发现读取的配置文件不同 ```bash # 没有指定配置文件,默认使用的是 /usr/local/nginx/conf/nginx.conf nginx -t # 检测 /usr/local/abc.conf 文件语法是否正常 nginx -tc /usr/local/abc.conf ``` ![](https://img.itqaq.com/art/content/5dd23fa06ebcfa80211557a12ded1803.png) 当前,也可以在启动的时候指定配置文件,这种写法你可能在很多地方看到过 ```bash nginx -c /usr/local/abc.conf ``` ##### -g 在 nginx.conf 中可以看到有个配置项用于指定 master 进程 ID 存放位置,默认是注释掉的 ``` # pid logs/nginx.pid; ``` ![](https://img.itqaq.com/art/content/075b17c5d04ab35210ecb545470d16d9.png) 我们可以在启动 nginx 时使用 -g 参数补充配置,如:指定 master 进程 ID 存放位置 但是,一般情况下这些内容我们都会在 nginx.conf 中指定,很少通过 -g 参数指定配置 ```bash nginx -g "pid logs/abc.pid;" ``` ![](https://img.itqaq.com/art/content/6806140c04f27ead65b988e0a4f84581.png) 使用 -g 参数指定 master 进程 ID 存放位置后,停止 nginx 服务会出现问题 ```bash nginx -s stop ``` 可以发现并没有从 abc.pid 查找进程 ID,此时没有办法使用命令行关闭的 ![](https://img.itqaq.com/art/content/7eba059974e45e4a2607de9759d4879d.png) 但可以使用信号控制关闭 ```bash kill -TERM `cat /usr/local/nginx/logs/abc.pid` ``` ![](https://img.itqaq.com/art/content/08d1569b6d98ac7a950bab9b2c0f3eae.png)