本节我们讲述nginx配置文件相关的一些内容。
1. 相关静态函数声明
2. 相关变量定义
1) nginx配置模块支持的指令
这里nginx配置模块(conf module)当前只支持一个include
指令。其携带一个参数,可以放置于nginx配置文件的任意位置。在解析include
指令时,通过调用ngx_conf_include()
来完成。include
指令语法如下:
通过include
指令将file
文件,或者满足mask
匹配的文件包含到配置文件中来。所包含进来的文件必须满足nginx定义的相关语法。例如:
include mime.types;
include vhosts/*.conf
2) nginx配置模块
这里ngx_conf_module
并不需要任何模块上下文module context
,所支持的模块指令为ngx_conf_commands
,模块类型为NGX_CONF_MODULE
,在进程退出时的回调函数为ngx_conf_flush_files
。
3) 配置指令参数数组
3. 配置解析相关函数实现
3.1 函数ngx_conf_param()
本函数主要用于处理通过nginx命令行的-g
选项传递进来的参数。-g directives
是用于设置全局配置指令的,例如:
# nginx -g "pid /var/run/nginx.pid; worker_processes `sysctl -n hw.ncpu`;"
通过nginx命令行-g
选项传递进来的参数保存在cf->cycle->conf_param
中。函数首先构造一个conf_file对象,用于表示当前的一个配置文件:
再接着调用ngx_conf_parse()
当前的配置对象.
3.2 函数ngx_conf_parse()
在nginx_auto_config.h头文件中,我们有如下定义:
#ifndef NGX_SUPPRESS_WARN
#define NGX_SUPPRESS_WARN 1
#endif
接下来我们分几个部分来对ngx_conf_parse()
进行讲解:
1) 判断解析类型
ngx_conf_parse()函数支持解析三种类型的配置: parse_file、parse_block、parse_param。
- parse_file类型: 当
filename
不为NULL时,表示要解析的是一个配置文件。此时需要进行一些相应的前期处理:
2) 解析配置指令
3.3 函数ngx_conf_handler()
1) 函数流程分析
下面我们简要分析一下该函数(这里注意cf->args包含了指令及参数部分):
2) 指令的配置上下文
上面说道建立指令的配置上下文
,下面我们来看一下cf->ctx
这个数据结构是如何建立的,这个ctx
大概是一个怎样的数据结构。主要参考代码位置src/core/ngx_cycle.c源文件的ngx_init_cycle()函数:
从上面我们可以看到,首先建立了一个ngx_max_module
大小的指针数组,然后再针对NGX_CORE_MODULE
类型的模块调用:
来创建相应的上下文存放在该模块对应的索引处。属于NGX_CORE_MODULE
的主要有以下几个:
下面我们就来简单的分析ngx_core_module
、ngx_events_module
、ngx_http_module
这三个比较有代表性的模块,看其create_conf()到底是怎么创建起配置上下文
的。
3) ngx_core_module模块
通过查看源代码,我们可以看到其实是创建了一个ngx_core_conf_t
数据结构,以此作为该模块配置指令上下文的。
4) ngx_events_module模块
这里我们可以看到,并没有通过module->create_conf
创建其配置指令上下文的,但是我们可以看到:
这里创建了一个二级指针数组,来存放上下文。
5) ngx_http_module模块
这里我们可以看到,并没有通过module->create_conf
创建其配置指令上下文,但是我们可以看到:
这里创建了一个ngx_http_conf_ctx_t作为其上下文,其中main_conf
、srv_conf
、loc_conf
又是指向一个指针数组,最后再指向相应的上下文。
5) ngx_cycle_s.conf_ctx结构示意图
通过上面的分析,我们可以刻画出4级指针的一个整体结构:
注意:
1) 上述ctx_index的初始化是在src/core/ngx_module.c的ngx_count_modules()中完成
2) 只有属于NGX_CORE_MODULE类型的模块才在cycle->conf_ctx数组中有相应的入口。
这里我们以解析http模块的server指令为例:
http{
server{
listen 80;
}
server{
listen 81;
}
}
在解析到http指令时,调用ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last), 此时cf->ctx值为cycle->conf_ctx
;而到了解析server指令时,再调用到ngx_conf_handler()函数时,cf->ctx的值为ngx_http_conf_ctx_t
。
6) 建立指令上下文部分代码分析
对于NGX_DIRECT_CONF
类型,例如上图中的ngx_core_conf_t
,直接将4级指针强制转换成2级指针即可;
对于NGX_MAIN_CONF
类型,例如上图中的ngx_events_module
以及ngx_http_module
,则直接保存的地址是&conf_ctx[module_index];
对于其他类型,则保存对应数组在ctx_index
索引处的地址, 例如对于ngx_event_core_module
,由于cf->ctx当前指向的就是上面所构建的这个无名指针
,因此这里confp
就是这个无名指针
指向的地址。
7) nginx module的启动流程
首先在ngx_init_cycle()
中为cycle->conf_ctx分配空间,然后针对ngx_modules[]数组中的每一个NGX_CORE_MODULE
类型的元素,调用其cycle->modules[i]->ctx的create_conf()来创建context; 再接着完成nginx -g
选项传递进来的全局指令的解析,然后完成nginx配置文件的解析; 最后再针对ngx_modules[]数组中每一个NGX_CORE_MODULE
类型的元素调用cycle->modules[i]->ctx的init_conf()来完成最后配置的一个初始化。
针对非NGX_CORE_MODULE
类型的module,则在解析到对应配置块时调用该模块的ngx_module_s.ctx结构来完成上下文的建立。
[参看]
-
初识nginx——配置解析篇
-
Nginx 配置项参数解析
-
Nginx开发从入门到精通
-
Nginx——-配置文件解析ngx_conf_handler
-
Command-line parameters
-
图解Nginx 中的4级指针