nginx程序管理之master程序
阿新 • • 發佈:2019-02-03
nginx分為single和 master兩種程序模型。master模型為一個master模型和n個worker程序的工作方式 。本文分析nginx的 master程序做了哪些事情,它是如何管理好各個worker程序的。
在main函式中完成了nginx啟動初始化過程,啟動初始化過程中的一個重要環節就是解析配置檔案,回撥各個配置指令的回撥函式,因此完成了各個模組的配置相互關聯。在完成初始化後,就呼叫ngx_master_process_cycle,這個函式具體做了什麼事情。
上面遮蔽一系列的訊號,以防建立worker程序時,被打擾。sigemptyset(&set); sigaddset(&set, SIGCHLD); sigaddset(&set, SIGALRM); sigaddset(&set, SIGIO); sigaddset(&set, SIGINT); sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL)); if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed"); }
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
ngx_start_cache_manager_processes(cycle, 0);
這裡開始建立worker子程序,master程序就是通過依次呼叫這兩個函式來建立子程序。第一個呼叫的函式建立的子程序稱為worker程序,第二個呼叫的函式建立的就是有關cache的子程序。接收請求,完成響應的就是worker程序。
此處就是迴圈建立n個worker程序,fork新程序的具體工作在ngx_spawn_process函式中完成。這裡涉及到一個全域性陣列ngx_processes(src/os/unix/ngx_process.c),陣列的長度為NGX_MAX_PROCESSES(預設為 1024),儲存的元素型別是ngx_process_t(src/os/uninx/ngx_process.h檔案)。全域性陣列ngx_processes就是用來儲存每個子程序的相關資訊,如pid,channel,程序做具體事情的介面指標等,這 些資訊就是用結構體ngx_process_t來描述的。在ngx_spawn_process建立好一個worker程序返回 後,master程序就將worker程序的pid,worker程序在ngx_processes陣列中的位置及channel[0]傳遞給前面建立好的worker程序,然後迴圈建立下一個worker程序。channel是用socketpair建立的,用於程序間通訊。master和worker程序以及worker程序之間都可以通過這樣的一個通道進行通訊。for (i = 0; i < n; i++) { ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type); ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); }
ngx_start_cache_manager_processes函式和start_worker的工作相關無幾。接著master程序就陷入死迴圈中守護著worker程序。在master_cycle中呼叫了sigsuspend,因而master程序掛起,等待訊號的產生(收到訊號,呼叫訊號處理函式,設定對應的全域性變數,sigsuspend函式返回,判斷全域性變數並採取相應的動作)
if (ngx_quit) {
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
ls = cycle->listening.elts;
for (n = 0; n < cycle->listening.nelts; n++) {
if (ngx_close_socket(ls[n].fd) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[n].addr_text);
}
}
cycle->listening.nelts = 0;
continue;
}
對SIGQUIT訊號進行的處理動作。呼叫ngx_signal_worker_processes函式向每個worker程序遞送SIGQUIT訊號,通知worker程序退出工作,然後關閉所有的監聽套接字。用continue是為了子程序傳送SIGCHLD訊號給master程序,讓master程序為其善後。
if (ngx_reap) {
ngx_reap = 0;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");
live = ngx_reap_children(cycle);
}
此時,ngx_reap為1,master程序呼叫ngx_reap_children處理所有的worker程序。
master程序就這些。