Nginx平滑升級源碼分析

1、平滑升級步驟nginx

一、重命名以前的sbin/nginx文件,將新的nginx文件放到sbin/目錄下socket

#mv ./sbin/nginx ./sbin/nginx.old函數

#cp ~/nginx ./sbin/源碼分析

二、向正在運行的nginx發送USR2信號啓動新的nginx,這個時候新老nginx都會接收請求,看那一個進程能搶到鎖,搶到鎖的worker進程能夠accpet新請求ui

#kill -USR2  `cat nginx.pid`spa

三、觀察新的nginx運行無誤後,向舊nginx發信號 中止舊nginx的運行3d

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

 

 

2、源碼分析blog

1,nginx啓動時 設置信號監聽函數,監聽信號隊列

src/core/nginx.c  

NewImage

368行 ngx_init_signals函數 設置要監聽的信號,和信號的處理函數

 

src/core/nginx.c  

NewImage

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

 

sig的定義以下

NewImage

QUIT和USR2的信號處理函數都爲 ngx_signal_handler

對應的流程圖爲

NewImage

 

 

二、master進程經過sigsuspend掛起在信號監聽處

NewImage

 

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

ngx_signal_handler處理USR2信號

src/os/unix/ngx_process.c

NewImage

372行  設置了ngx_change_binary=1

 

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

src/os/unix/ngx_process.c

NewImage

277行 ngx_exec_new_binary經過fork啓動新的nginx bin文件

 

src/core/nginx.c

NewImage

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

NewImage

src/os/unix/ngx_process.c

NewImage

src/os/unix/ngx_process.c

 

對應的流程圖以下

 

NewImage

 

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

master進程收到QUIT信號後,將ngx_quit置爲1

NewImage

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

NewImage

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

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

 

src/os/unix/ngx_process_cycle.c

NewImage

504行 經過kill函數向全部worker進程發送信號

 

五、worker進程收到NGX_SHUTDOWN_SIGNAL(QUIT)信號

src/os/unix/ngx_process.c 

NewImage

360行 worker進程將ngx_quit置爲1

NewImage

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

NewImage

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

1067行 銷燬內存池

對應的流程圖以下

NewImage 

 

六、子進程退出後,做爲父進程的master進程會收到SIGCHLD信號

src/os/unix/ngx_process.c

NewImage

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

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

 

src/os/unix/ngx_process.c

NewImage

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

 

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

NewImage

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

NewImage

619 若是worker至今纔是由於意外退出的,而且能夠重啓,則調用ngx_spawn_process從新啓動一個worker子進程

642 若是有worker進程還在運行則live=1 若是所有的worker子進程都已經退出則live=0

 

src/os/unix/ngx_process_cycle.c

NewImage

656行 ngx_delete_pidfile 刪除pid文件

666行 ngx_close_listening_sockets 關閉監聽端口

685行 銷燬內存池

686行 退出

對應的流程圖以下

NewImage

相關文章
相關標籤/搜索