1 事件模块基本配置
static ngx_command_t ngx_events_commands[] = {
{ ngx_string("events"),
NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_events_block,
0,
0,
NULL },
ngx_null_command
};
static ngx_core_module_t ngx_events_module_ctx = {
ngx_string("events"),
NULL,
ngx_event_init_conf
};
ngx_module_t ngx_events_module = {
NGX_MODULE_V1,
&ngx_events_module_ctx, /* module context */
ngx_events_commands, /* module directives */
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
static ngx_str_t event_core_name = ngx_string("event_core");
static ngx_command_t ngx_event_core_commands[] = {
{ ngx_string("worker_connections"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_event_connections,
0,
0,
NULL },
{ ngx_string("connections"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_event_connections,
0,
0,
NULL },
{ ngx_string("use"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_event_use,
0,
0,
NULL },
{ ngx_string("multi_accept"),
NGX_EVENT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_event_conf_t, multi_accept),
NULL },
{ ngx_string("accept_mutex"),
NGX_EVENT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_event_conf_t, accept_mutex),
NULL },
{ ngx_string("accept_mutex_delay"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
0,
offsetof(ngx_event_conf_t, accept_mutex_delay),
NULL },
{ ngx_string("debug_connection"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_event_debug_connection,
0,
0,
NULL },
ngx_null_command
};
ngx_event_module_t ngx_event_core_module_ctx = {
&event_core_name,
ngx_event_core_create_conf, /* create configuration */
ngx_event_core_init_conf, /* init configuration */
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
ngx_module_t ngx_event_core_module = {
NGX_MODULE_V1,
&ngx_event_core_module_ctx, /* module context */
ngx_event_core_commands, /* module directives */
NGX_EVENT_MODULE, /* module type */
NULL, /* init master */
ngx_event_module_init, /* init module */
ngx_event_process_init, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
2 基本执行流程
2.1 ngx_init_cycle函数
该函数执行nginx的初始化工作,其中最重要的是解析nginx.conf的配置文件
2.2 events模块的解析过程
2.2.1 基本信息介绍
事件是nginx中的最主要的基础模块,所以下面就来看下nginx是如何解析events模块的,在nginx.conf中有events的配置信息如下
- events在nginx.conf中的配置信息
events {
use epoll;
worker_connections 1024;
accept_mutex on;accept_mutex_delay 500;
debug_connection 192.168.1.1;
epoll_events ;
multi_accept on;
}
- 与events对应的nginx中的结构体
既然有events的模块,在nginx的程序中就要使用这些配置信息,所以用如下结构题ngx_event_conf_t来表示events模块,从这个结构体中看出,其与events有对应的参数关系,下面将会介绍程序是如何通过解析events中的参数,对结果提ngx_event_conf_t进行填充的
typedef struct {
ngx_uint_t connections;
ngx_uint_t use;
ngx_flag_t multi_accept;
ngx_flag_t accept_mutex;
ngx_msec_t accept_mutex_delay;
u_char *name;
#if (NGX_DEBUG)
ngx_array_t debug_connection;
#endif
} ngx_event_conf_t;
- ngx_cycle_t
ngx_cycle_t管理了与nginx生命周期相关的所有配置信息,结构体如下
struct ngx_cycle_s {
void ****conf_ctx;
ngx_pool_t *pool;
ngx_log_t *log;
ngx_log_t new_log;
ngx_uint_t log_use_stderr; /* unsigned log_use_stderr:1; */
ngx_connection_t **files;
ngx_connection_t *free_connections;
ngx_uint_t free_connection_n;
ngx_module_t **modules;
ngx_uint_t modules_n;
ngx_uint_t modules_used; /* unsigned modules_used:1; */
ngx_queue_t reusable_connections_queue;
ngx_array_t listening;
ngx_array_t paths;
ngx_array_t config_dump;
ngx_list_t open_files;
ngx_list_t shared_memory;
ngx_uint_t connection_n;
ngx_uint_t files_n;
ngx_connection_t *connections;
ngx_event_t *read_events;
ngx_event_t *write_events;
ngx_cycle_t *old_cycle;
ngx_str_t conf_file;
ngx_str_t conf_param;
ngx_str_t conf_prefix;
ngx_str_t prefix;
ngx_str_t lock_file;
ngx_str_t hostname;
};
其中有两个重要的成员变量void ****conf_ctx和ngx_module_t **modules,conf_ctx存储解析到的配置信息,不同的模块由不同的结构体表示,结构提指针存储在conf_ctx中,modules中是nginx中所有模块的数组,在configure后的nginx源文件下的objs中有个ngx_modules.c中可以看到一个全局数组ngx_modules存储了nginx中的所有模块,下面以图的给出这两个变量的存储结构
来自 http://blog.csdn.net/initphp/article/details/52434261
2.2.2 nginx解析events模块过程
基本流程
解析的基本流程如下,主要是在ngx_init_cycle中的ngx_conf_parse完成nginx.conf的解析工作,当然也包括解析events模块
来自:http://blog.chinaunix.net/uid-26335251-id-3483044.html详解events解析过程
1 首先进入ngx_conf_parse函数,首先判断如果有nginx.conf的文件路径,则打开配置文件。
2 接着进入一个for循环,开始解析nginx.conf配置文件,每次ngx_conf_read_token解析一行,,解析到的配置参数存储在cf.args中,当解析到envens时候,由于这是一个模块,程序判断到由**{**开始,接着程序进入ngx_conf_handler函数。
3 在ngx_conf_handler中,由于刚才解析到的是events参数,即name=cf->args->elts,在这个函数里有个for循环,将cf->cycle->modules中的模块与当前解析到的events模块匹配,决定调用哪个回调函数(**modules变量稍后介绍**),经过比对,发现cf->cycle->modules中第4个位置的ngx_events_module匹配,然后执行rv = cmd->set(cf, cmd, conf),即调用了ngx_events_commands中的回调函数ngx_events_block方法。
4 在ngx_events_block中完成如下几件事:a)创建结构体指针,
*ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *)); if (*ctx == NULL) {
return NGX_CONF_ERROR;
}
*(void **) conf = ctx;
conf就是外部传递进来的cf->ctx中的存储结构提指针的位置,所以就是在cf->ctx中开辟一个指针存储位置,
然后在ngx_event_core_create_conf函数中为分配一个ngx_event_conf_t类型的空间,把它的地址放到刚才开辟的cf->ctx中;b)调用 ngx_conf_parse函数,注意此时传递进去的nginx.conf文件路径finaname为NULL,此时ngx_conf_read_token会解析出events中的
use epoll;
worker_connections 1024;
等参数,当解析到use参数时,依然调用 ngx_conf_handler函数,在这个函数中,依然是遍历modules中的模块,对于use将会发现其与ngx_event_core_module_ctx模块的ngx_event_core_commands中的
{ ngx_string("use"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_event_use,
0,
0,
NULL },
子项相关,所以在ngx_connection_t中的调用rv = cmd->set(cf, cmd, conf);会进入ngx_event_use函数中,在ngx_event_use中对cf->ctx中(即ngx_cycle_t中的conf_ctx)存储的ngx_event_conf_t结构成员进行赋值,即将use赋成2,name赋成epoll;
当参数解析到worker_connections参数时,即对应与ngx_event_core_commands中的信息
{ ngx_string("worker_connections"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_event_connections,
0,
0,
NULL }
即调用ngx_event_connections,在该函数中将cf->ngx中存储的ngx_event_conf_t的connections成员设置成1024
c)说明:events中其它参数也和use,connections的解析过程一样,至此events的解析过程介绍完毕。