欢迎登陆真网站,您的到来是我们的荣幸。 登陆 注册 忘记密码? ☆设为首页 △加入收藏
欢迎加入真幸福QQ群
电脑知识: 基础知识 网络技术 操作系统 办公软件 电脑维修 电脑安全 windows7 windows8 windows10 服务器教程 平板电脑 视频播放教程 网络应用 互联网 工具软件 浏览器教程 QQ技巧 输入法教程 影视制作 YY教程 wps教程 word教程 Excel教程 PowerPoint
云南西双版纳特产小花糯玉米真空包装


不设密码怎么让无线网络安全?
win7旗舰版系统下如何给浏览器设置密码
XP系统无法配置此无线连接怎么解决
XP系统提示计算机可能存在风险怎么解决
电脑出现应用程序发生异常未知的软件异常怎么办
XP系统文字输入法不能切换怎么办
XP系统怎么安装Ubuntu实现Samba文件共享
XP系统任务管理器无法运行怎么办
XP系统如何在不同网段共享打印机
XP系统怎么打开IIS
Nginx 配置文件解析
【 来源:网络 】【 点击:1 】 【 发布时间:2017_03_03 08:59:59 】

  cycle = ngx_init_cycle(&init_cycle):

  1、在内存池中分配一个ngx_cycle_t变量,并初始化它的各个成员。

  2、调用core类型的create_conf,实际只有一个ngx_core_module_create_conf函数----初始化ngx_core_conf_t结构(存放core_module支持的指令),保存在ngx_cycle->conf_ctx数组中。可以说,此时,ngx_cycle->conf_ctx数组中只有一个ngx_core_conf_t结构。

  3、初始化ngx_conf_t结构。

  4、ngx_conf_parse 解析配置文件,把结果保存在模块对应的ngx_conf里面。

  5、调用core类型的init_conf,实际只有一个ngx_core_module_init_conf函数(初始化对应的ngx_core_conf_t函数)。为什么要init,都已经解析配置文件了,应该在这之前初始化呀--如果值为-1,表明没有设置,初始化默认值!

  6、ngx_open_listening_sockets:遍历listening数组并打开所有侦听sockets(socket()->setsockopt()->bind()->listen())。

  7、调用所有模块的init_module(实际上只有ngx_event_core_module模块定义了该callback,即只有ngx_event_module_init()被调用)。

  ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename):

  函数的作用就是循环不停的从配置文件中读取指令,然后进行指令处理,直到结束

  1、先分析ngx_core_module的指令及其对应的set函数。

  { ngx_string("daemon"),

  NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,

  ngx_conf_set_flag_slot,

  0,

  offsetof(ngx_core_conf_t, daemon),

  //计算daemon成员在ngx_core_conf_t结构体里面的偏移

  NULL },

  ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf):里面代码很清楚,根据配置指令,设置模块conf结构的成员变量。

  2、分析ngx_events_modules的指令及其对应的set函数。只有一条指令:

  { ngx_string("events"),

  NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,

  ngx_events_block,

  0,

  0,

  NULL },

  1、ngx_events_module编号为3,于是ngx_cycle->conf_ctx指向的void*数组第3号槽位指向一个void*指针,这个指针又指向一个void*数组(个数==事件类型模块的个数,Linux平台编译之后,只有两个ngx_epoll_module事件模型ngx_event_core_module和ngx_epoll_module)。

  2、调用event类型模块的上下文ngx_event_module_t 的create_conf钩子,为void*数组指定槽位创建相应的conf结构。

  3、更改当前cf环境(NGX_EVENT_MODULE,NGX_EVENT_CONF)解析events{ 块里面的指令。里面的set函数都是根据配置文件设置ngx_event_conf_t结构体里面的成员变量。

  3、分析ngx_http_module的指令及其对应的set函数。只有一条指令,如下:

  { ngx_string("http"),

  NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,

  ngx_http_block,

  0,

  0,

  NULL },

  ngx_init_cycle创建了core module的config,那么http module相关的config在那里创建呢?http module相关的config是在ngx_http_block中创建(ngx_http_conf_ctx_t)的,在ngx_http_block中会创建,初始化,合并config(未完全看懂),以及整个http handler phase的初始化(还未看)等等。

 

1、为ngx_cycle->conf_ctx指向的void*数组创建ngx_http_conf_ctx_t结构,并为ngx_http_conf_ctx_t 创建main_conf srv_conf loc_conf三个void*数组,数组大小为http类型模块的个数。
2、遍历所有的http类型的模块的上下文ngx_http_module_t,调用create_main_conf、create_srv_conf、create_loc_conf 分别在ngx_http_conf_ctx_t 的三个数组(main_conf srv_conf loc_conf)的对应槽位创建响应的结构体变量。
3、遍历所有的http类型的模块的上下文ngx_http_module_t, 调用 preconfiguration 钩子函数。
4、解析http块里面的指令:ngx_conf_parse 未看,当前环境:ctx指向ngx_http_conf_ctx_t,指令类型为NGX_HTTP_MAIN_CONF,模块类型为:NGX_HTTP_MODULE。
4.1、 遇到http里面的main指令:
if (cmd->type & NGX_DIRECT_CONF) {
conf = ((void **) cf->ctx)[ngx_modules[i]->index]; //ngx_core_conf_t
} else if (cmd->type & NGX_MAIN_CONF) {
//hp: 比如,遇到http/events指令,这里,conf指向的是cf->ctx的第idx个槽位
conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
} else if (cf->ctx) {
//否则进入二级模块处理,比如events/http {里面的指令,都是在这里

//http 里面的main指令,ctx指向于ngx_http_conf_ctx_t
confp = *(void **) ((char *) cf->ctx + cmd->conf); //这里,cmd->conf的作用体现出来了
if (confp) {
//http里面的main指令: conf指向的是对应的ngx_http_core_main_conf_t
conf = confp[ngx_modules[i]->ctx_index];
}
}
比如variables_hash_max_size 指令:
{ ngx_string("variables_hash_max_size"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot, //这里,刚好设置conf(ngx_http_core_main_conf_t) 的variables_hash_max_size的值。
NGX_HTTP_MAIN_CONF_OFFSET, //这里,conf+NGX_HTTP_MAIN_CONF_OFFSET就是需要设置的结构体==ngx_http_core_main_conf_t变量地址
offsetof(ngx_http_core_main_conf_t, variables_hash_max_size), //需要设置结构体中的哪个成员,成员在结构体中的偏移。
NULL },
总结出struct ngx_command_s { // 这个域主要是供nginx解析配置文件时使用,设置相关的数据结构
ngx_str_t name;
//命令名称
ngx_uint_t type;
//命令类型(有几个参数等)
char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); //这个conf指向需要设置的结构体变量地址
ngx_uint_t conf;
//配置结构体在内存的位置,相对于conf的偏移量,在ngx_conf_handler中使用
ngx_uint_t offset;
//要设置结构体的哪个成员,相对于结构体的偏移量
void *post;
 

  //一些读取配置时候的零碎变量,一般为null

  };

  4.2 遇到 server指令时:

  生成一个新的ngx_http_conf_ctx_t,其中main_conf指向原来的,server_conf和loc_conf创建新的void*数组。把ngx_http_core_module的server块配置信息存入 main_conf 中的server 容器里面。更新当前环境。 开始解析server块里面的指令。

  cf->ctx = ctx; //指向新的ngx_http_conf_ctx_t

  cf->cmd_type = NGX_HTTP_SRV_CONF;

  4.3 遇到server里面的指令:遇到listen 指令时,ngx_conf_handler中,confp指向的新的ngx_http_conf_ctx_t.srv_conf所指向的void*数组,于是 conf = confp[ngx_modules[i]->ctx_index];指向listen指令对应的模块(ngx_htt_core_module)的 ngx_http_core_srv_conf_t数据结构。

  4.4 遇到location指令:生成一个新的ngx_http_conf_ctx_t,其中main_conf指向原来的,srv_conf指向上一层ngx_http_conf_ctx_t的srv_conf数组,loc_conf创建新的void*数组。

  ngx_http_core_location 这个函数很麻烦,看起来主要是设置ngx_http_loc_conf_ctx_t里面的name变量。然后递归调用ngx_parse_conf解析location里面的命令。

  4.5: 遇到location里面的命令。比如 root,设置ngx_http_loc_conf_ctx_t里面的root变量。

  5、回到ngx_http_block函数!遍历每个http类型的模块,调用模块上下文ngx_http_module_t中的init_main_conf钩子初始化模块对应的main_conf配置信息,然后调用ngx_http_merge_servers。

本网站由川南居提供技术支持,fkzxf版权所有 浙ICP备12031891号
淳安分站 淳安分站