nginx源码分析
nginx-1.11.1
参考书籍《深入理解nginx模块开发与架构解析》
Nginx的master与worker工作模式
在生成环境中的Nginx启动模式基本都是以master/worker为主进行启动运行,通过master/worker的工作方式可以利用多核系统的并发处理能力,master主要就是负责与worker进程进行通信,控制并负载每个worker进程的连接处理以达到worker进程的负载均衡,本文就开始分析一下该模式
master的启动过程
信号相关初始化
在Nginx中的工作方式,进程间的通信基于信号的较多,通过信号来实现相关进程的管理工作,在初始化的过程中,有注册了相关信号的初始化。
ngx_signal_t signals[] = {
{ ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
"SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
"reload",
ngx_signal_handler }, // 重新加载信号处理
{ ngx_signal_value(NGX_REOPEN_SIGNAL),
"SIG" ngx_value(NGX_REOPEN_SIGNAL),
"reopen",
ngx_signal_handler }, // 日志重新打开信号处理
{ ngx_signal_value(NGX_NOACCEPT_SIGNAL),
"SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
"",
ngx_signal_handler },
{ ngx_signal_value(NGX_TERMINATE_SIGNAL),
"SIG" ngx_value(NGX_TERMINATE_SIGNAL), // 停止信号
"stop",
ngx_signal_handler },
{ ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
"SIG" ngx_value(NGX_SHUTDOWN_SIGNAL), // 退出信号
"quit",
ngx_signal_handler },
{ ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
"SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
"",
ngx_signal_handler },
{ SIGALRM, "SIGALRM", "", ngx_signal_handler },
{ SIGINT, "SIGINT", "", ngx_signal_handler },
{ SIGIO, "SIGIO", "", ngx_signal_handler },
{ SIGCHLD, "SIGCHLD", "", ngx_signal_handler },
{ SIGSYS, "SIGSYS, SIG_IGN", "", SIG_IGN },
{ SIGPIPE, "SIGPIPE, SIG_IGN", "", SIG_IGN },
{ 0, NULL, "", NULL }
};
ngx_int_t
ngx_init_signals(ngx_log_t *log) // 注册相关信号处理函数
{
ngx_signal_t *sig;
struct sigaction sa;
for (sig = signals; sig->signo != 0; sig++) { // 遍历信号列表
ngx_memzero(&sa, sizeof(struct sigaction)); // 内存清零 sa
sa.sa_handler = sig->handler; // 获取处理的handler
sigemptyset(&sa.sa_mask);
if (sigaction(sig->signo, &sa, NULL) == -1) { // 设置信号处理
#if (NGX_VALGRIND)
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"sigaction(%s) failed, ignored", sig->signame);
#else
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"sigaction(%s) failed", sig->signame);
return NGX_ERROR;
#endif
}
}
return NGX_OK; // 信号处理成功
}
主要是注册了相关的信号处理函数ngx_signal_handler,
void
ngx_signal_handler(int signo)
{
char *action;
ngx_int_t ignore;
ngx_err_t err;
ngx_signal_t *sig;
ignore = 0;
err = ngx_errno;
for (sig = signals; sig->signo != 0; sig++) { // 判断信号是否在列表中
if (sig->signo == signo) { // 住过找到
break;
}
}
ngx_time_sigsafe_update(); // 更新时间
action = "";
switch (ngx_process) {
case NGX_PROCESS_MASTER:
case NGX_PROCESS_SINGLE:
switch (signo) {
case ngx_signal_value(NGX_SHUTDOWN_SIGNAL): // 判断相关信号并赋值相关标志位
ngx_quit = 1;
action = ", shutting down";
break;
case ngx_signal_value(NGX_TERMINATE_SIGNAL):
case SIGINT:
ngx_terminate = 1;
action = ", exiting";
break;
...
}
信号初始化完成之后,就继续执行master的初始化。
master/worker的初始化
在初始化完成之后,就进入ngx_master_process_cycle的执行,
void
ngx_master_process_cycle(ngx_cycle_t *cycle)
{
char *title;
u_char *p;
size_t size;
ngx_int_t i;
ngx_uint_t n, sigio;
sigset_t set;
struct itimerval itv;
ngx_uint_t live;
ngx_msec_t delay;
ngx_listening_t *ls;
ngx_core_conf_t *ccf;
sigemptyset(&set);