nginx事件模块解析

来源:互联网 发布:阿里云备案核验单下载 编辑:程序博客网 时间:2024/05/16 18:17

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中的所有模块,下面以图的给出这两个变量的存储结构
Alt text
配置文件解析流程图
来自 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成员设置成1024c)说明:events中其它参数也和use,connections的解析过程一样,至此events的解析过程介绍完毕。
0 0