[TOC] #### 1. 前言 --- nginx 安裝后,接下來(lái)我們就要學(xué)習(xí)如何啟動(dòng)、停止、重啟 nginx 的服務(wù) 對(duì)于 nginx 服務(wù)的啟??刂疲?linux 系統(tǒng)中也有多種方式,比如:信號(hào)控制、命令行控制 信號(hào)控制:使用 nginx 服務(wù)的信號(hào)來(lái)控制,這種方式里面涉及到一些信號(hào),重點(diǎn)是理解這些信號(hào)所代表的含義 命令行控制:使用 sbin 目錄下的 nginx 可執(zhí)行的二進(jìn)制文件來(lái)控制,這種方式日常開(kāi)發(fā)中使用的比較多,非常重要 #### 2. 信號(hào)控制 --- 信號(hào)控制:只需要給 master 進(jìn)程發(fā)送信號(hào)就可以來(lái)控制 nginx,在學(xué)習(xí)日志分割、服務(wù)升級(jí)時(shí)會(huì)用到信號(hào)控制這種方式 想要操作 nginx 的 master 進(jìn)程,就需要獲取到 master 進(jìn)程的進(jìn)程 ID(PID) ##### a. 查看主進(jìn)程 ID **方式一:運(yùn)行以下命令查看 nginx 進(jìn)程** ```bash ps -ef | grep nginx ```  **方式二:通過(guò) nginx.pid 文件查看 master 進(jìn)程 PID** 在使用 `./configure` 命令預(yù)編譯時(shí),有兩個(gè)參數(shù) `--prefix=PATH` 用于指定 nginx 安裝目錄,`--pid-path=PATH` 用于指定 nginx 主進(jìn)程 IP 存放位置,默認(rèn)存放位置是 nginx 安裝目錄下的 `logs/nginx.pid` 文件中 運(yùn)行以下命令查看 nginx 安裝信息 ```bash /usr/local/nginx/sbin/nginx -V ``` 發(fā)現(xiàn)安裝目錄為 `/usr/local/nginx`,未指定 pid 存放目錄,則主進(jìn)程 ID 存放位置為 `/usr/local/nginx/logs/nginx.pid`  運(yùn)行以下命令查看文件內(nèi)容,也就是 nginx 的 master 進(jìn)程 ID ```bash cat /usr/local/nginx/logs/nginx.pid ```  ##### b. 信號(hào)控制用法 獲取到 nginx 的主進(jìn)程 ID 之后,能干什么 | 信號(hào) | 作用 | 等同于 | | ------------ | ------------ | ------------ | | TERM/INT | 立即關(guān)閉整個(gè)服務(wù) | nginx -s stop | | QUIT | "優(yōu)雅" 的關(guān)閉整個(gè)服務(wù),worker 進(jìn)程處理完當(dāng)前用戶(hù)請(qǐng)求再關(guān)閉 | nginx -s quit | | HUP | 重讀配置文件并使用服務(wù)對(duì)新配置項(xiàng)生效 | nginx -s reload | | USR1 | 重新打開(kāi)日志文件,可以用來(lái)進(jìn)行日志切割 | nginx -s reopen | | USR2 | 平滑升級(jí)到最新版的 nginx | - | | WINCH | 所有子進(jìn)程不在接收處理新連接,相當(dāng)于給 worker 進(jìn)程發(fā)送 QUIT 指令 | - | 調(diào)用命令: ```bash # signal:信號(hào) # PID:nginx 的 master 線(xiàn)程 ID kill -[signal] PID ``` 使用示例: ```bash # TERM:立即關(guān)閉 nginx 服務(wù),1294 是 master 進(jìn)程 ID kill -TERM 1294 # QUIT:優(yōu)雅的關(guān)閉 nginx 服務(wù),1294 是 master 進(jìn)程 ID kill -QUIT 1294 ``` 也可以使用下面這種寫(xiě)法,將 master 進(jìn)程的 ID 改為命令輸出結(jié)果,就不需要查看進(jìn)程 ID 值了 ```bash kill -TERM `cat /usr/local/nginx/logs/nginx.pid` ``` USR1 信號(hào):發(fā)送該信號(hào)給 master 進(jìn)程,告訴 nginx 重新開(kāi)啟日志文件 ```bash # 刪除日志文件 rm -rf /usr/local/nginx/logs/access.log /usr/local/nginx/logs/error.log # 運(yùn)行以下命令會(huì)重新創(chuàng)建 access.log、error.log kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` ``` USR2信號(hào):告訴 master 進(jìn)程要平滑升級(jí),將 nginx 從低版本升級(jí)到高版本,無(wú)需重啟 nginx 服務(wù),不影響用戶(hù)訪(fǎng)問(wèn)  通過(guò)這兩步操作之后,運(yùn)行在服務(wù)器上的就是最新開(kāi)啟的 master 進(jìn)程,具體怎么實(shí)現(xiàn)我們通過(guò)實(shí)例看下效果 給 master 進(jìn)程發(fā)送 USR2 信號(hào),可以看到打開(kāi)了一份新的 master、worker 進(jìn)程 ```bash kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` ```  如下圖所示,USR2 信號(hào)會(huì)生成 `nginx.pid.oldbin` 文件,用于記錄舊的 master 進(jìn)程 ID  假設(shè)我們確保 nginx 服務(wù)器已經(jīng)升級(jí)成功,接下來(lái)運(yùn)行以下命令 它的作用是等待舊的 worker 進(jìn)程處理完用戶(hù)請(qǐng)求后,將舊的 worker 進(jìn)程和 master 進(jìn)程都關(guān)閉掉 ```bash kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin` ``` 執(zhí)行完命令之后,就可以發(fā)現(xiàn)只剩下新的 master、worker 進(jìn)程  WINCH 信號(hào):所有子進(jìn)程不在接收處理新連接,只關(guān)閉 woker 進(jìn)程,不關(guān)閉 master 進(jìn)程 ```bash kill -WINCH `cat /usr/local/nginx/logs/nginx.pid` ```  **QUIT 信號(hào) 和 WINCH 信號(hào)的區(qū)別?** 都是等 worker 進(jìn)程處理完當(dāng)前用戶(hù)請(qǐng)求再將 worker 進(jìn)程關(guān)閉掉,WINCH 信號(hào)到此就結(jié)束了,而不會(huì)關(guān)閉 master 進(jìn)程,但是 QUIT 信號(hào)會(huì)將 master 進(jìn)程也關(guān)閉掉 #### 3. 命令行控制 --- 命令行控制:這種方式是使用 sbin 目錄下的 nginx 可執(zhí)行的二進(jìn)制文件來(lái)進(jìn)行 nginx 狀態(tài)的控制 執(zhí)行二進(jìn)制文件的寫(xiě)法示例 ```bash # 相對(duì)路徑 cd /usr/local/nginx/sbin ./nginx -s reload # 絕對(duì)路徑 /usr/local/nginx/sbin/nginx -s reload # 定義了環(huán)境變量或命令別名 nginx -s reload ``` 運(yùn)行以下命令查看都有哪些參數(shù)可用 ```bash nginx -h ``` | 參數(shù) | 描述 | | ------------ | ------------ | | -? 和 -h | 顯示幫助信息 | | -v | 查看 nginx 版本號(hào) | | -V | 查看 nginx 版本號(hào)和配置信息 | | -t | 測(cè)試配置文件語(yǔ)法是否正確 | | -T | 測(cè)試配置文件語(yǔ)法是否正確,并輸出用到的配置文件 | | -q | 配置測(cè)試期間不顯示非錯(cuò)誤消息 | | -p | 指定 nginx 的 prefix 路徑,默認(rèn)為:/usr/local/nginx | | -c | 指定 nginx 的 配置文件路徑,默認(rèn)為:conf/nginx.conf | | -g | 用于補(bǔ)充 nginx 配置,向 nginx 服務(wù)指定啟動(dòng)時(shí)應(yīng)用全局的配置 |  ##### -h ```bash # 下面兩個(gè)命令作用是一樣的 nginx -? nginx -h ``` ##### -v ```bash # 查看版本號(hào) nginx -v # 查看版本號(hào)和配置信息 nginx -V ```  ##### -q ```bash # 檢測(cè)配置文件語(yǔ)法,運(yùn)行命令可以看到?jīng)]有錯(cuò)誤信息,是正常的提示 nginx -t # 因?yàn)闆](méi)有錯(cuò)誤信息,所以什么也沒(méi)有輸出(不顯示非錯(cuò)誤信息) nginx -tq ```  當(dāng)有錯(cuò)誤信息時(shí),才會(huì)輸出內(nèi)容  ##### -s 給 master 進(jìn)程發(fā)送信號(hào)控制 nginx 的狀態(tài),可用的信號(hào):stop, quit, reopen, reload ```bash # 快速關(guān)閉,類(lèi)似于 TERM/INT 信號(hào)的作用,直接關(guān)閉 master、worker 進(jìn)程 nginx -s stop # 優(yōu)雅關(guān)閉,類(lèi)似于 QUIT 信號(hào)的作用,等待 worker 進(jìn)程處理完請(qǐng)求再關(guān)閉 master、worker 進(jìn)程 nginx -s quit # 重新打開(kāi)日志文件,類(lèi)似于 USR1 信號(hào)的作用 nginx -s reopen # 重載配置文件,類(lèi)似于 HUP 信號(hào)的作用 nginx -s reload ``` ##### -c `-c` 參數(shù)用于指定 nginx 使用的配置文件,默認(rèn)使用的是 nginx 安裝目錄下的 `conf/nginx.conf` 接下來(lái),我們看下具體效果 首先,我們使用默認(rèn)的 nginx.conf 創(chuàng)建出一個(gè)新的配置文件,用于測(cè)試使用 ```bash # 拷貝 nginx.conf 得到新的配置文件 abc.conf cp /usr/local/nginx/conf/nginx.conf /usr/local/abc.conf ``` 為了區(qū)分兩個(gè)配置文件,我們修改一下 abc.conf,故意造成語(yǔ)法錯(cuò)誤  運(yùn)行以下命令進(jìn)行語(yǔ)法檢測(cè),查看命令輸出就可以發(fā)現(xiàn)讀取的配置文件不同 ```bash # 沒(méi)有指定配置文件,默認(rèn)使用的是 /usr/local/nginx/conf/nginx.conf nginx -t # 檢測(cè) /usr/local/abc.conf 文件語(yǔ)法是否正常 nginx -tc /usr/local/abc.conf ```  當(dāng)前,也可以在啟動(dòng)的時(shí)候指定配置文件,這種寫(xiě)法你可能在很多地方看到過(guò) ```bash nginx -c /usr/local/abc.conf ``` ##### -g 在 nginx.conf 中可以看到有個(gè)配置項(xiàng)用于指定 master 進(jìn)程 ID 存放位置,默認(rèn)是注釋掉的 ``` # pid logs/nginx.pid; ```  我們可以在啟動(dòng) nginx 時(shí)使用 -g 參數(shù)補(bǔ)充配置,如:指定 master 進(jìn)程 ID 存放位置 但是,一般情況下這些內(nèi)容我們都會(huì)在 nginx.conf 中指定,很少通過(guò) -g 參數(shù)指定配置 ```bash nginx -g "pid logs/abc.pid;" ```  使用 -g 參數(shù)指定 master 進(jìn)程 ID 存放位置后,停止 nginx 服務(wù)會(huì)出現(xiàn)問(wèn)題 ```bash nginx -s stop ``` 可以發(fā)現(xiàn)并沒(méi)有從 abc.pid 查找進(jìn)程 ID,此時(shí)沒(méi)有辦法使用命令行關(guān)閉的  但可以使用信號(hào)控制關(guān)閉 ```bash kill -TERM `cat /usr/local/nginx/logs/abc.pid` ``` 