Nginx平滑升級源碼分析,nginx源碼

來源:互聯網
上載者:User

Nginx平滑升級源碼分析,nginx源碼

一、平滑升級步驟

1、重新命名之前的sbin/nginx檔案,將新的nginx檔案放到sbin/目錄下

#mv ./sbin/nginx ./sbin/nginx.old

#cp ~/nginx ./sbin/

2、向正在啟動並執行nginx發送USR2訊號啟動新的nginx,這個時候新老nginx都會接收請求,看那一個進程能搶到鎖,搶到鎖的worker進程可以accpet新請求

#kill -USR2  `cat nginx.pid`

3、觀察新的nginx運行無誤後,向舊nginx發訊號 停止舊nginx的運行

#kill -QUIT `cat nginx.pid.oldbin`

 

 

二、源碼分析

1,nginx啟動時 設定訊號監聽函數,監聽訊號

src/core/nginx.c  

368行 ngx_init_signals函數 設定要監聽的訊號,和訊號的處理函數

 

src/core/nginx.c  

291-293行 訊號為sig->signo,對應的處理函數為sig->handler

 

sig的定義如下

QUIT和USR2的訊號處理函數都為 ngx_signal_handler

對應的流程圖為

 

 

2、master進程通過sigsuspend掛起在訊號監聽處

 

3,向master進程id發送USR2訊號

ngx_signal_handler處理USR2訊號

src/os/unix/ngx_process.c

372行  設定了ngx_change_binary=1

 

master進程接收到訊號,從掛起狀態恢複,繼續執行

src/os/unix/ngx_process.c

277行 ngx_exec_new_binary通過fork啟動新的nginx bin檔案

 

src/core/nginx.c

589行 ngx_set_evviroment 設定新nginx bin的環境變數

640行 ngx_rename_file 通過rename函數將nginx.pid檔案重新命名為nginx.pid.oldbin

651行 ngx_execute 啟動新的bin檔案

由於nginx老master進程fork出的新nginxmaster進程,他們可以監聽同一個連接埠,所以新nginx和老nginx可以同時監聽連接埠,具體誰執行看哪一個worker子進程搶到了鎖,可以accpet新串連 

 

src/os/unix/ngx_process.c

src/os/unix/ngx_process.c

src/os/unix/ngx_process.c

 

對應的流程圖如下

 

 

4、向老的nginx進程發送QUIT訊號,從容關閉

master進程收到QUIT訊號後,將ngx_quit置為1

master進程接收到訊號,從掛起狀態恢複,繼續執行

209行 ngx_signal_worket_processes 向worker進程發送 NGX_SHUTDOWN_SIGNAL(QUIT)訊號

215行 ngx_close_socket 主進程關閉監聽的socket

 

src/os/unix/ngx_process_cycle.c

504行 通過kill函數向所有worker進程發送訊號

 

5、worker進程收到NGX_SHUTDOWN_SIGNAL(QUIT)訊號

src/os/unix/ngx_process.c 

360行 worker進程將ngx_quit置為1

worker進程收到訊號後從epoll_wait中喚醒從ngx_process_events_and_timers函數中恢複,

710-714行 發現ngx_quit=1後將ngx_quit恢複為0,ngx_exiting置為1,

713行 通過ngx_close_listening_sockets關閉處理的socket

609行 下一次迴圈發現ngx_exiting=1後,處理隊列中的已有事件和逾時事件,發現沒有要處理的事件了,就通過ngx_worker_process_exit退出worker進程

 

src/os/unix/ngx_process_cycle.c

1024行 調用各個模組的exit_process方法

1067行 銷毀記憶體池

對應的流程圖如下

 

 

6、子進程退出後,作為父進程的master進程會收到SIGCHLD訊號

src/os/unix/ngx_process.c

387行 父進程收到SIGCHLD後將ngx_reap置為1,

437行 發現訊號是SIGCHLD後執行ngx_process_get_status函數判斷worker子進程是正常退出,還是異常退出

 

src/os/unix/ngx_process.c

494-499行 如果發現worker子進程如果是正常退出的,會將exited置為1

 

master進程接收到訊號,從掛起狀態恢複,繼續執行

176行 發現ngx_reap=1後,ngx_reap_children函數判斷是否需要重啟worker進程

如果worker是因為收到了quit訊號正常退出的,所有worker進程退出時,live=0

183行 live=0 並且收到了ngx_quit訊號  通過ngx_master_process_exit關閉master進程

 

src/os/unix/ngx_process_cycle.c

619 如果worker至今才是因為意外退出的,並且可以重啟,則調用ngx_spawn_process重新啟動一個worker子進程

642 如果有worker進程還在運行則live=1 如果全部的worker子進程都已經退出則live=0

 

src/os/unix/ngx_process_cycle.c

656行 ngx_delete_pidfile 刪除pid檔案

666行 ngx_close_listening_sockets 關閉監聽連接埠

685行 銷毀記憶體池

686行 退出

對應的流程圖如下

 

 

 

 

 

 

PS:推薦一個好朋友的公眾號,一個每天都在思考或者在思考路上的公眾號運營少女~

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.