控制 nginx
變更設定 輪換日誌檔 即時升級可執行檔 |
nginx 可以透過訊號來控制。預設情況下,主程序的程序 ID 會寫入 /usr/local/nginx/logs/nginx.pid
檔案中。此名稱可以在設定時變更,或者在 nginx.conf
中使用 pid 指令變更。主程序支援以下訊號
TERM, INT 快速關閉 QUIT 優雅關閉 HUP 變更設定,跟上時區變更(僅適用於 FreeBSD 和 Linux),使用新設定啟動新的 worker 程序,優雅關閉舊的 worker 程序 USR1 重新開啟日誌檔 USR2 升級可執行檔 WINCH 優雅關閉 worker 程序
個別的 worker 程序也可以透過訊號控制,儘管不是必須的。支援的訊號如下
TERM, INT 快速關閉 QUIT 優雅關閉 USR1 重新開啟日誌檔 WINCH 異常終止以進行偵錯(需要啟用 debug_points)
變更設定
為了讓 nginx 重新讀取設定檔,應向主程序傳送 HUP 訊號。主程序首先檢查語法有效性,然後嘗試套用新設定,也就是開啟日誌檔和新的監聽 socket。如果失敗,則會回滾變更並繼續使用舊設定。如果成功,則會啟動新的 worker 程序,並向舊的 worker 程序傳送訊息,要求它們優雅關閉。舊的 worker 程序會關閉監聽 socket 並繼續服務舊的用戶端。在所有用戶端都服務完畢後,舊的 worker 程序會關閉。
讓我們用例子來說明。假設 nginx 在 FreeBSD 上執行,命令
ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
會產生以下輸出
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 33127 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) 33128 33126 nobody 0.0 1364 kqread nginx: worker process (nginx) 33129 33126 nobody 0.0 1364 kqread nginx: worker process (nginx)
如果向主程序傳送 HUP,則輸出會變成
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33129 33126 nobody 0.0 1380 kqread nginx: worker process is shutting down (nginx) 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx)
其中一個 PID 為 33129 的舊 worker 程序仍然繼續運作。過一段時間後,它會退出
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx)
輪換日誌檔
為了輪換日誌檔,首先需要重新命名它們。之後,應向主程序傳送 USR1 訊號。主程序將重新開啟所有目前開啟的日誌檔,並將執行 worker 程序時所使用的非特權使用者指定為擁有者。成功重新開啟後,主程序會關閉所有開啟的檔案,並向 worker 程序傳送訊息,要求它們重新開啟檔案。Worker 程序也會立即開啟新檔案並關閉舊檔案。如此一來,舊檔案幾乎可以立即用於後處理,例如壓縮。
即時升級可執行檔
為了升級伺服器可執行檔,應首先將新的可執行檔放在舊檔案的位置。之後,應向主程序傳送 USR2 訊號。主程序首先會將其程序 ID 的檔案重新命名為新的檔案,並加上 .oldbin
後綴,例如 /usr/local/nginx/logs/nginx.pid.oldbin
,然後啟動新的可執行檔,而新的可執行檔又會啟動新的 worker 程序
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
之後,所有 worker 程序(舊的和新的)都會繼續接受請求。如果向第一個主程序傳送 WINCH 訊號,它會向其 worker 程序傳送訊息,要求它們優雅關閉,它們將開始退出
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33135 33126 nobody 0.0 1380 kqread nginx: worker process is shutting down (nginx) 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
過一段時間後,只有新的 worker 程序會處理請求
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
應該注意的是,舊的主程序不會關閉其監聽 socket,如果需要,可以管理它再次啟動其 worker 程序。如果因為某些原因,新的可執行檔無法接受地運作,可以執行以下操作之一
-
向舊的主程序傳送 HUP 訊號。舊的主程序將啟動新的 worker 程序,而不會重新讀取設定。之後,可以透過向新的主程序傳送 QUIT 訊號,優雅關閉所有新程序。
-
向新的主程序傳送 TERM 訊號。它會向其 worker 程序傳送訊息,要求它們立即退出,它們將幾乎立即全部退出。(如果新程序因為某些原因沒有退出,應向它們傳送 KILL 訊號以強制它們退出。)當新的主程序退出時,舊的主程序會自動啟動新的 worker 程序。
如果新的主程序退出,則舊的主程序會從程序 ID 的檔案名稱中捨棄 .oldbin
後綴。
如果升級成功,則應向舊的主程序傳送 QUIT 訊號,只有新的程序會留下來
PID PPID USER %CPU VSZ WCHAN COMMAND 36264 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)