leevis.com
leevis.com copied to clipboard
nginx的master和worker模式
概述
main函数中,根据master_process的配置,如果开启则为master worker模式,则会调用ngx_master_process_cycle函数启动worker进程。在调用该函数启动worker进程前,会调用ngx_init_signals函数注册信号回调。
- ngx_master_process_cycle函数: 在该函数中,调用了ngx_start_worker_processes启动worker进程。
// 启动worker进程
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
// 启动cache进程
ngx_start_cache_manager_processes(cycle, 0);
- ngx_start_worker_processes函数: 在该函数中ngx_spawn_process是封装了fork函数和创建父子进程通信的channel,用来启动worker进程的。ngx_worker_process_cycle是函数指针,worker实际的运行函数。
static void
ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
{
ngx_int_t i;
ngx_channel_t ch;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
ngx_memzero(&ch, sizeof(ngx_channel_t));
ch.command = NGX_CMD_OPEN_CHANNEL;
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_spawn_process函数:
函数原型:
ngx_pid_t
ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
char *name, ngx_int_t respawn)
- 遍历ngx_processes[] 数组,从中寻找一个空的,用来保存子进程的状态等。
- 调用socketpair创建无名管道,并设置为异步非阻塞。管道的读端保存到ngx_channel全局变量,数组下标保存到ngx_process_slot全局变量中。这两个全局变量非常重要,子进程会用。
- 调用fork函数创建子进程,子进程则运行proc这个函数指针指向的函数。父进程则搜集子进程的信息保存到ngx_processes数组对应的下标中。
- 父进程返回子进程的pid,并继续执行程序中的逻辑。
子进程
-
子进程函数ngx_worker_process_cycle:
- 调用ngx_worker_process_init初始化子进程。
- 循环调用ngx_process_events_and_timers函数,处理子进程的事件。
- 根据状态(ngx_exiting、ngx_quit、ngx_reopen)处理子进程自身。
-
ngx_worker_process_init函数:
- 设置环境变量env
- 设置进程优先级。
- 设置进程打开文件最大值。
- 设置coredump文件大小。
- 绑定cpu核心。
- 修改工作目录。
- 清除屏蔽信号。
- 调用所有模块的init_process()函数指针指向的函数。
- 关闭管道父进程写端。
- 添加管道处理回调函数ngx_channel_handler。
父进程
在ngx_master_process_cycle函数中,调用ngx_start_worker_processes创建子进程,父进程会返回继续执行。
- 父进程调用sigsuspend函数阻塞,等待信号唤醒。
- 当有信号时,首先会执行信号注册的回调函数(修改对应的flag),然后父进程从sigsuspend处接着往下执行。
- 根据信号设置的对应的flag,处理对应的情况。
例如,当master接受到SIGWINCH(NGX_NOACCEPT_SIGNAL)信号时,会回调该信号的处理函数ngx_signal_handler,把ngx_noaccept设置为1,父进程从sigsuspend处唤醒继续执行。当ngx_noaccept为真时,调用ngx_signal_worker_processes函数向工作进程发送SIGQUIT(NGX_SHUTDOWN_SIGNAL)信号。 子进程注册的管道处理回调被唤醒执行,最终设置ngx_quit=1.子进程主循环当ngx_quit为真时,会调用ngx_set_shutdown_timer、ngx_close_listening_sockets、ngx_close_idle_connections 并设置ngx_exiting=1。子进程主循环ngx_exiting为真时判断事件是否处理完毕,处理完毕则调用ngx_worker_process_exit函数退出子进程。
-
ngx_signal_worker_processes函数 该函数会调用处理信号对应到channel的一个结构。循环子进程数组,通过管道把该结构发送给子进程,如果管道发送失败,会发送信号给子进程。同时修改子进程对应的信息。
-
ngx_set_shutdown_timer函数 注册超时回调处理已经建立连接上的请求。
-
ngx_close_listening_sockets函数 关闭监听。
-
ngx_close_idle_connections函数 关闭空闲连接。
reading...