您的位置:首页 > 其它

ngx_init_cycle的详细分析

2014-12-02 16:26 267 查看
本文档的Copyleft归L.L所有,使用GPL发布,可以自由转载,转载时请务必以超链接形式标明文章原始出处,严禁用于任何商业用途。

email: cc.dd.14@163.com

来源: http://blog.csdn.net/ccdd14

 

 

继续分析ngx_init_cycle函数,该函数以init_cycle作为实参,而ngx_cycle是指向它的。ngx_init_cycle一上来就是更新时区和时间,why?必要吗?

 

紧跟着创建一个NGX_CYCLE_POOL_SIZE大小的内存池,并在该内存池上创建了新的cycle(类型为ngx_cycle_t),然后初始化成员pool、log、new_log、conf_prefix、prefix、conf_file、conf_param、pathes、open_files、shared_memory、listening,值得一提的是cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module
* sizeof(void *)),这个成员在以后索引相应模块的context配置信息非常重要,很快就会看到它的用处。

 

下面的代码遍历类型为NGX_CORE_MODULE的各个模块,调用模块context里注册的create_conf函数,该钩子函数基本是初始化配置信息,并将返回的配置信息保存在cycle->conf_ctx中。

[cpp]
view plaincopy

for (i = 0; ngx_modules[i]; i++) {  
    if (ngx_modules[i]->type != NGX_CORE_MODULE) {  
        continue;  
    }  
    module = ngx_modules[i]->ctx;  
    if (module->create_conf) {  
        rv = module->create_conf(cycle);  
        if (rv == NULL) {  
            ngx_destroy_pool(pool);  
            return NULL;  
        }  
        cycle->conf_ctx[ngx_modules[i]->index] = rv;  
    }  
}  

 
 

开始深入到各NGX_CORE_MODULE模块里的create_conf分析:

1. ngx_core_module模块,对应的钩子函数是ngx_core_module_create_conf,主要工作就是创建ngx_core_conf_t结构,该结构成员表示的意思可以查看网址http://wiki.nginx.org/NginxChsHttpMainModule,thanks
wiki;

2. ngx_errlog_module模块,对应的钩子函数是NULL,让人省事的NULL;

3. ngx_events_module模块,又见到可爱的NULL;

4. ngx_http_module模块,多来些NULL吧。

这么看来,上面的代码好像也没做啥事情。

 

配置信息,嗯,到了初始化conf(类型为ngx_conf_t),注意conf.ctx = cycle->conf_ctx,

conf.module_type = NGX_CORE_MODULE,conf.cmd_type = NGX_MAIN_CONF。进入ngx_conf_param函数。如果启动nginx时,使用了-g选项,那么这个函数就是用来分析后面所带的参数,否则,直接退出。

 

看看ngx_conf_parse,它的解析分三种类型:parse_file(如果形参带的filename有效,那就打开文件,建立缓冲区),parse_block(这个是文件的内容已经装到缓冲区了,分析{}里面的内容),parse_param(这个就是处理-g选项所带的参数或者是解析出来的参数)。

 

ngx_conf_read_token函数就是读取配置文件nginx.conf里的内容,取得name-value对。cf->handler当前为NULL。

 

ngx_conf_handler函数遍历类型为NGX_CORE_MODULE或NGX_CONF_MODULE的模块,调用这些模块commands里的set钩子,取得相应的value。如果commands的type=NGX_CONF_BLOCK,那么则需last=NGX_CONF_BLOCK_START,否则,则需

last=NGX_OK。然后取得本地conf的地址,这个地址就是cycle->conf_ctx对应的模块索引(还记得conf.ctx = cycle->conf_ctx?)。

然后是各模块的set钩子分析:

1. ngx_core_module模块,commands注册为ngx_core_commands,它里面注册的set钩子很多,但都比较简单,就是取得对应name的value,需要关注的是name=worker_processes,这是启动工作者进程的个数;

2. ngx_errlog_module模块,commands注册为ngx_errlog_commands,它里面只注册了一个set钩子-----ngx_error_log。

nginx.conf里关于log的常见配置可能是这样的格式:error_log  logs/error.log debug,所以value[1]=logs/error.log,

value[2]=debug。ngx_conf_open_file是将value[1]加入到前面新创建的cycle里的open_files。如果没有配置后面的debug,则log

的默认级别为NGX_LOG_ERR。ngx_log_set_levels函数是遍历配置的log级别,对其进行有效性判断,最后,如果log级别为NGX_LOG_DEBUG,则重设为NGX_LOG_DEBUG_ALL,意味着打开所有级别的信息;

3. ngx_conf_module模块,commands注册为ngx_conf_commands,也只是注册了一个set钩子-----ngx_conf_include,专门用来分析include配置,使用strpbrk和glob实现功能;

4. ngx_events_module模块,commands注册为ngx_events_commands,依然只注册了一个set钩子-----ngx_events_block,不过这是初始化过程中一个非常重要的函数;

{//花括号内的分析都是针对ngx_events_module

ngx_events_block函数先对类型为NGX_EVENT_MODULE的模块建立ctx_index索引,最大模块数保存在ngx_event_max_module。接着是遍历调用NGX_EVENT_MODULE模块的create_conf钩子,进去看看到底又做了啥?

a. ngx_event_core_module模块,context注册为ngx_event_core_module_ctx,create_conf钩子为ngx_event_create_conf,它的作用就是创建一个ngx_event_conf_t结构,该结构成员表示的意思可以查看网址

http://wiki.nginx.org/NginxChsHttpEventsModule,thanks wiki too;

b. ngx_epoll_module模块(epoll,让人有些激动),context注册为ngx_epoll_module_ctx,看看它的样子,非常重要。

[cpp]
view plaincopy

ngx_event_module_t  ngx_epoll_module_ctx = {  
    &epoll_name,  
    ngx_epoll_create_conf,               /* create configuration */  
    ngx_epoll_init_conf,                 /* init configuration */  
    {  
        ngx_epoll_add_event,             /* add an event */  
        ngx_epoll_del_event,             /* delete an event */  
        ngx_epoll_add_event,             /* enable an event */  
        ngx_epoll_del_event,             /* disable an event */  
        ngx_epoll_add_connection,        /* add an connection */  
        ngx_epoll_del_connection,        /* delete an connection */  
        NULL,                            /* process the changes */  
        ngx_epoll_process_events,        /* process the events */  
        ngx_epoll_init,                  /* init the events */  
        ngx_epoll_done,                  /* done the events */  
    }  
};  

 
create_conf钩子为ngx_epoll_create_conf,它的作用非常简单,仅创建一个ngx_epoll_conf_t,而ngx_epoll_conf_t也非常简单,仅events一个成员,表示每个进程处理的最大事件数,啊哈!简单多好。

上面两个模块创建的conf最终保存在cf->ctx中,并重置cf->module_type = NGX_EVENT_MODULE,

cf->cmd_type = NGX_EVENT_CONF。再次调用ngx_conf_parse,这时type=parse_block,接着又进入了ngx_conf_handler(这玩意看起来支持可重入吗?),又是调用set钩子函数,变的是轮到NGX_EVENT_MODULE模块了。好吧,一个个来:

a. ngx_event_core_module模块,commands注册为ngx_event_core_commands,set钩子为...嗯...很多,重要的是ngx_event_connections,获取每个进程处理的最大连接数,保存在cf->cycle->connection_n = ecf->connections;

b. ngx_epoll_module模块,commands注册为ngx_epoll_commands,set钩子为ngx_conf_set_num_slot,获取每个进程处理的最大事件数,将值赋给ngx_epoll_conf_t里的events。

 

set钩子处理完成后,继续遍历调用NGX_EVENT_MODULE模块的init_conf钩子。还是一个个来:

a. ngx_event_core_module模块,init_conf钩子为ngx_event_init_conf,linux平台先测试epoll模型是否可用,接着就是对

ngx_event_conf_t赋初值,每个进程的最大连接数默认为connections=512;

b. ngx_epoll_module模块,init_conf钩子为ngx_epoll_init_conf,默认设置每个进程处理的最大事件数events=512。

}

 

5. ngx_http_module模块,commands注册为ngx_http_commands,set钩子为ngx_http_block,这个也很复杂......

 

作为惯例,复杂的留待下一章分析.......
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: