nginx多進程模型之配置熱加載---轉


http://blog.csdn.net/brainkick/article/details/7176405

前言:

       服務器程序通常都會通過相應的配置文件來控制服務器的工作。很多情況下,配置文件會經常地被修改,在使其生效時,我們都希望不重啟程序,不影響服務器的正常服務。所以所謂的配置文件”熱加載”就成了一項非常重要的功能,而這方面,nginx給我們樹立了非常好的榜樣,值得我們去學習和借鑒。

 

分析:

       在nginx正常服務時,我們在nginx的程序程序目錄執行./nginx –sreload,來實現重新加載配置文件。-s的作用是向master進程發送信號,除了reload功能之外,還可以使用stop,reopen等,具體地可以通過-h來查看。

 

當執行了./nginx –s reload之后,通過ngxs_signal來保存”reload”字符串,然后通過ngx_signal_process 來向當期正在運行的nginxmaster進程發送信號。代碼如下:

if (ngx_signal) {

       return  ngx_signal_process(cycle, ngx_signal);

}

通過讀代碼我們看到,向當前運行的nginx進程發送信號,實際上就是重啟一份nginx,不過這個nginx並不會作為一個server啟動起來,它替我們發送完信號之后就退出了。所以對於nginx的一些控制有些是不需要我們使用kill來操作的,nginx幫我們做了一下封裝,我們使用的時候也就方便了。

具體地,nginx是如何幫我們發送信號的呢?其實很簡單,我們知道nginx有個pid文件,里面記錄了,當前正在運行的nginxmaster進程的pid,所以程序會通過這個文件得到進程的pid,和信號字符串對應的signo,最后使用kill來完成信號的發送。

Nginx初始化階段通過ngx_init_signals函數來初始化信號操作。在ngx_process.c中定義了一個signals數組。

  1. typedef struct {  
  2.   
  3.     int    signo;                  // 信號值  
  4.   
  5.     char  *signame;               // 信號值對應的字面名  
  6.   
  7.     char  *name;                 // nginx下的別名  
  8.   
  9.     void (*handler)(int signo);  // 信號處理函數  
  10.   
  11. } ngx_signal_t;  
  12.   
  13.    

我們看到”reload”其實是SIGHUP信號的封裝,也就是說我們可以直接通過kill向nginx發送SIGHUP信號來完成reload操作。

這里我們重點關注信號處理函數:ngx_signal_handler。

所以當我們執行nginx –s reload時,ngx_signal_handler就會執行了。

在ngx_signal_handler中,ngx_process表示當前進程的類型,在信號處理時,對於不同的進程,處理是不一樣的,這里通過switch case來作區分。我們主要關注masterprocess,即NGX_PROCESS_MASTER類型。代碼如下:

  1. casengx_signal_value(NGX_RECONFIGURE_SIGNAL):  
  2.   
  3.     ngx_reconfigure = 1;  
  4.   
  5.     action = ", reconfiguring";  
  6.   
  7. break;  

我們發現當前進程中的全局變量ngx_reconfigure被置成了1,這樣在ngx_master_process_cycle的for循環中檢測到ngx_reconfigure ==1,就開始做重加載配置的操作了。

         后續的動作就很明顯了。通過ngx_start_worker_processes開啟新進程,而之前的進程則通過ngx_signal_worker_processes,來發送信號來“優雅”的關閉,所謂優雅的關閉,是指當前真正處理請求的進程會等到處理完之后再退出,同時當前的進程停止listen,不再accept新的請求了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM