您的位置:首页 > 运维架构 > Nginx

文章2:nginx启动过程之main函数

2012-12-30 18:38 656 查看
欢迎转载,转载请注明出处/article/1389068.html
本文主要是nginx启动过程中关于main函数部分的初始化。

1)ngx_get_options:获得运行时的一些选项。

-g ngx_conf_params

运行命令执行完ngx_get_options后,全局变量
./nginx -c /usr/local/nginx/conf/nginx.confu_char* ngx_conf_file = " /usr/local/nginx/conf/nginx.conf"
$./nginx -s stop u_char * ngx_signal = "stop"
$./nginx -s reload u_char * ngx_signal = "reload"
$./nginx -t -c /usr/local/nginx/conf/nginx.conf
$./nginx -h ngx_show_version = 1 ngx_show_help = 1;
$./nginx -Vngx_show_version = 1; ngx_show_configure = 1;
$./nginx -p /usr/local/nginxngx_prefix = /usr/local/nginx 。
ngx_prefix指定Nginx工作目录。其error.log及nginx.conf都会在该目录下被找到。
ngx_prefix会在多处使用:1)ngx_log_init中2)在ngx_process_options中会其ngx_prefix的取值赋值给ngx_cycle的conf_prefix和prefix成员变量。

2)ngx_process_options

用来将ngx_get_options中获得这些参数取值赋值到ngx_cycle中。包括:ngx_cycle中的conf_prefix,prefix,conf_file,conf_param,log->log_level等。

3)全局变量 volatile ngx_cycle_t * ngx_cycle处理。

ngx_cycle = &init_cycle;

4)ngx_save_argv将argc 和*argv[]的信息保存到ngx_argv和ngx_argc中,其中argv数组的每个元素会对应的保存到ngx_argv数组中。这算是一个备份存储,方便以后master进程做热代码替换之用。

$./nginx -p /usr/local/nginx 则ngx_argv数组保存argv中信息,ngx_argc保存argc信息。则ngx_argc = 3 ngx_argv[0] = /usr/local/nginx/sbin/nginx

ngx_argv[1]=-p

ngx_argv[2]=/usr/local/nginx

5)ngx_os_init进行系统的一些初始化工作。

获得ngx_pagesize,ngx_ncpu,ngx_max_sockets,ngx_inherited_nonblocking等信息。

6)ngx_add_inherited_sockets。

将继承的套接字添加到ngx_cycle的listening array中。但是啥是继承套接字啊 不知道了~~参考文章nginx源码分析—处理继承的sockets and 运行和控制
Nginx - 命令行参数和信号 继承套接字用于程序的热启动。

7)这个for循环非常重要,

因为它确定了每个module在ngx_module数组中的位置。ngx_module_t中index指示这个module在ngx_module数组中的位置。nginx在编译的时候会生成一个目录objs,该目录下有一个文件ngx_modules.c,该文件中 有ngx_module[]数组。比如ngx_core_module的index为0.

ngx_max_module = 0;

for (i = 0; ngx_modules[i]; i++) {

ngx_modules[i]->index = ngx_max_module++;

}

8)ngx_init_cycle(&init_cycle);

这是初始化过程中非常重要的一个初始化函数。
cycle = ngx_init_cycle(&init_cycle);

ngx_cycle = cycle;
ngx_init_cycle主要做了以下工作,利用old_cycle创建一个新的new_cycle。
1)将old_cycle中成员变量赋值给new_cycle的成员变量

2)为new_cycle中的一些成员变量分配空间

3)依次调用NGX_CORE_MODULE模块的create_conf钩子函数,

4)调用ngx_conf_param和ngx_conf_parse函数解析,将配置文件nginx.conf中关于CORE模块的指令存入相应的变量中。

5)打开cycle_open_files中文件

6)创建共享内存区

7)操作监听套接字。非常关键的一步。

8)调用每个模块的init_module钩子函数

9)关闭和删除old_cycle中的一些成员。

主要就是做了这么几件事情:(1)CORE模块配置的文件的解析,将其存入程序的相应变量中(2)创建共享内存区 (3)监听套接字的处理 (4)调用每个模块的init_module函数

9)ngx_signal_process

主要是处理来自于$./nginx -s xxx的参数。详见文章2:Nginx与信号相关的内容
首先:从存放pid的文件中读取pid 然后关闭文件
其次:进入ngx_os_signal_process
遍历signal数组,找到匹配的信号并通过kill 将信号传递给进程,让进程根据信号做相应处理。kill并不是杀死的意思,kill是传递信号的意思。
if (ngx_signal) {

return ngx_signal_process(cycle, ngx_signal);

}

10)ngx_init_signal函数

通过sigaction函数设置signal数组中与指定信号相关联的处理动作。这儿详见文章2:nginx中与信号相关的内容

11)ngx_daemon函数

对于没有继承套接字并且配置文件中daemon on;时,调用ngx_daemon,创建守护进程。这儿是创建守护进程的标准做法。在APUE中有说明。

12)ngx_create_pidfile函数

13)ngx_process

的获取在main函数中
if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {

ngx_process = NGX_PROCESS_MASTER;

}
最后根据ngx_process是单进程还是多进程,分别调用不同的cycle
if (ngx_process == NGX_PROCESS_SINGLE) {

ngx_single_process_cycle(cycle);

} else {

ngx_master_process_cycle(cycle);

}
参考文章 http://www.alidata.org/archives/1092
http://www.alidata.org/archives/1148
/article/1451046.html
/article/1451045.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: