首先讓咱們瞭解一下各類信號的意義,咱們後面會用到其中的幾個:nginx
TERM,INT 快速退出日誌
QUIT 優雅退出(等待全部鏈接關閉後再退出程序,不接受新的鏈接)code
HUP 在修改配置後,以新的配置啓動worker進程,優雅退出舊的worker進程進程
USR1 從新打開日誌文件源碼
USR2 更新二進制文件編譯
WINCH 優雅地關閉worker進程(但不關閉master)ast
接下來是步驟:配置
這一步很簡單,新版本Nginx或者舊版本Nginx源碼加上新的編譯參數,在通過configure
和make
後,咱們在源碼目錄下的objs目錄中找到新的nginx二進制文件。二進制
注意,接下來請不要make install
。請求
將舊的nginx二進制文件備份一下:
cd /usr/local/nginx/sbin mv nginx nginx.old
而後將上一步獲得的新版本二進制文件複製過來:
cp /path/to/source/nginx /usr/local/nginx/sbin/
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
這一步發生了什麼?
master進程首先重命名PID文件,在文件名後添加.oldbin
後綴,好比nginx.pid
會被重命名爲nginx.pid.oldbin
。接着依次啓動新的執行文件和新的worker進程。這時候咱們觀察系統的進程,能夠看到有兩個master進程:
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)
注意這兩個master進程的PID:第一個進程的PPID是1,這是舊master進程,而新master進程的PPID就是舊master進程的PID,這說明新的master來自於舊的master。
這時候,新舊兩種worker同時接受鏈接請求。
接下來,發送WINCH信號給舊的master進程來「優雅」地關閉舊的Nginx worker:
kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`
過一段時間,咱們觀察系統進程:
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)
新舊兩個master進程都在,可是worker都是來自於新master。
那麼爲何咱們不直接用-QUIT退出舊master呢?由於假如這時咱們發現新worker進程由於一些緣由沒法接受請求,那咱們就能快速啓動舊Nginx。
快速回退的方法見最後。
升級很成功,新worker正常接受請求,那麼咱們就能夠關掉舊master了:
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
觀察系統進程:
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)
咱們看到,新master進程其PPID已經變成了1。
若是咱們在發送WINCH給舊master進程後發現新master沒法正常工做,咱們須要可以快速回退。
咱們通常用兩種方案來快速回退。