本文主要是nginx启动过程中关于main函数部分的初始化。
1)ngx_get_options:获得运行时的一些选项。
-g ngx_conf_params
运行命令 执行完ngx_get_options后,全局变量 ./nginx -c /usr/local/nginx/conf/nginx.conf u_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 -V ngx_show_version = 1; ngx_show_configure = 1; $./nginx -p /usr/local/nginx ngx_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等。
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); } |
版权声明:本文为博主原创文章,未经博主允许不得转载。