Nginx熱升級流程,看這篇就夠了

  • 2019 年 12 月 24 日
  • 筆記

在之前做過 Nginx 熱升級的演示,他能保證nginx在不停止服務的情況下更換他的 binary 文件,這個功能非常有用,但我們在執行 Nginx 的 binary 文件升級過程中,還是會遇到很多問題,比如老的 worker 進程一直退不掉或者新的 worker 進程升級以後出現問題需要考慮回滾,或者升級新的 Nginx 文件以後會發現預期的功能或者指向的配置文件出現了錯誤,下面我們來看下看熱升級的流程是怎樣進行的?

熱升級流程

第一步就是把舊的 Nginx 替換為新的 Nginx 文件(binary文件),之所以說只替換 binary 文件是因為大部分場景下,我們新編譯的 nginx 文件所指定的相應的配置選項,比如說配置文件的目錄在哪裡?log 的所在目錄在哪裡?必須保持和老的 Nginx 是一致的,否則的話沒有辦法復用 nginx.conf 文件,如果我們僅僅替換 binary 文件,請注意要備份,另外在新版本的 Linux 中,會要求在覆蓋一個正在使用的文件時需要用 cp -f 才能夠替換。

接下來我們像現在的老 master 進程發送 USR2 訊號,這時候我們注意到,我們沒有辦法通過 Nginx 命令行直接用 nginx -s 一個訊號來處理,因為 Nginx 到目前為止,還沒有支援這樣的訊號。

發送 USR2 訊號以後,現有的 master 進程會做以下幾件事情:修改 pid 文件名,加後綴 .oldbin,這是為什麼呢?這是在為新的 master 進程讓路,雖然 master、worker 進程都可以接受訊號,但是為了管理方便,通常不對 worker 進程直接發送訊號,所以我們依賴於 master 進程,他必須把他的 pid 保存下來,為了新的 master 使用 pid.bin 這個文件名,所以把老的 pid 文件改為 pid.oldbin。

接下來使用新的二進位文件啟動新的 master 進程,所以到此為止,會出現兩個 master 進程和老的 worker 進程,然後新的 master 進程會自動啟動新的 worker 進程,所以這時候我們會發現兩個 master 進程和多個 worker 進程的情況。

接下來我們要向老的 master 進程發送 QUIT 訊號,怎麼樣找到老的 master 進程呢?我們可以根據 ps 看到 master 進程的進程號,或者通過 .oldbin 文件找到老的 master 進程的進程號,向這個進程號發送 QUIT 訊號,那麼老的 master 進程會優雅的關閉老 worker 進程,這樣我們的熱升級就結束。

但是老 master 進程是一直保存下來的,這是為了方便我們進行回滾,也就是發現新的 Nginx 程式有問題了,這個時候因為老的 master 進程還在,可以向老的 master 進程發送 HUP 訊號,相當於執行了一次 reload,會啟動新的 worker 進程,然後再向新 master 進程發送 QUIT 訊號,也就是要求新的 worker 進程優雅退出,就實現了回滾。

接下來看下不停機更新 Nginx 二進位文件的具體流程圖:

不停機更新 Nginx 二進位文件

一開始老的 master 進程啟動了四個綠色的 worker 進程,當我們更新了Nginx 的 binary 以後,向老 master 進程發送了 SIGUSR2 訊號,這個時候老 master 進程會把自己的 pid 文件改名,這個時候可以認為是黃色這種的進程。

那麼啟動了新的 master 進程是怎麼樣啟動的呢?他啟動了新的子進程,也就是說新的 master 進程是老 master 進程的子進程,但這個子進程是使用了新的 binary 載入來啟動的,在中間這個流程新老 Nginx 並存,但是老的 master 開始關閉監聽埠,所有的黃色老的 worker 進程開始優雅地退出,在完成以後就會出現只有新的 master 進程存在的場景。

當退出老 master 進程以後不能進行回滾,如果想回滾,就需要再走一次熱升級流程,用備份好的老 Nginx 文件作為新的熱升級文件(因此建議備份舊的 Nginx 文件)。

在一個父進程退出,而它的一個或多個子進程還在運行時,那麼這些子進程將成為孤兒進程。孤兒進程將被 init 進程(進程號為1)所收養,並由 init 進程對它們完成狀態收集工作。所以老 master 進程退出後,新的 master 進程並不會退出。

以上就是熱升級流程,我們可以通過他實現不停機更新我們的 Nginx,這為我們持續使用 Nginx 的最新特性提供了幫助。

總結

這篇文章主要講解了 Nginx 熱升級的流程,希望在看完本文後可以使你在升級過程中若發生錯誤,知道該怎麼處理。

在熱升級之前,建議備份舊的 Nginx 文件,以防升級後出現問題,便於回滾。