[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)