Nginx 配置文件解析

sunguoli1982

sunguoli1982

2016-03-31 16:29

今天图老师小编要向大家分享个Nginx 配置文件解析教程,过程简单易学,相信聪明的你一定能轻松get!

Nginx 配置文件解析

  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 },

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/fuwuqi/)

  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 },

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/fuwuqi/)

  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 },

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/fuwuqi/)

  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

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/fuwuqi/)

  };

  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。

展开更多 50%)
分享

猜你喜欢

Nginx 配置文件解析

服务器
Nginx 配置文件解析

AndroidManifest.xml配置文件解析

编程语言 网络编程
AndroidManifest.xml配置文件解析

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Linux系统启动引导程序配置文件解析

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
Linux系统启动引导程序配置文件解析

squid的配置文件

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
squid的配置文件

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

透析PHP的配置文件

PHP
透析PHP的配置文件

JAVA高手解析XML配置文件的读取操作

编程语言 网络编程
JAVA高手解析XML配置文件的读取操作

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

iPhone使用小技巧

iPhone使用小技巧

猎豹浏览器抢票非法请求怎么办?

猎豹浏览器抢票非法请求怎么办?
下拉加载更多内容 ↓