文章20:NGINX配置文件格式及处理流程
来源:互联网 发布:mac开机风扇声音很大 编辑:程序博客网 时间:2024/06/05 06:18
欢迎转载,转载请注明出处http://blog.csdn.net/yankai0219/article/details/8286579
本文主要内容
0.序
一、NGINX配置文件的格式
1.构成
2.配置文件的格式决定了某些函数会被递归调用!原因:
3.配置项详细说明:
二、NGINX中结构体 与函数
1.存放指令取值的结构体
2. 存放指令的结构体
3. 与配置文件有关的函数
三、配置文件解析的流程
1.总流程
2.详细过程
NGX_CORE_MODULE、NGX_EVENT_MODULE、NGX_HTTP_MODULE
0.序
本文主要讲述了配置文件的格式以及NGINX如何获得配置文件的内容。阅读了很多大牛的文章,也阅读了代码中关于CORE HTTP EVENT模块对于配置文件的处理,现在将内容总结如下:
一、NGINX配置文件的格式
1.构成
Nginx配置文件是由多个配置项构成,每个配置项都有一个项目名和对应的项目值。配置项又分为简单配置项和复杂配置项。项目名又被称为指令(Directive),而项目值可能简单的字符串(以分号结尾),也可能是由简单字符串和多个配置项组合而成配置块的复杂结构(以大括号}结尾),因此我们可以将配置项归纳为两种:简单配置项和复杂配置项。
如下图所示:
2.配置文件的格式决定了某些函数会被递归调用!原因:
从上面这条规范可以看到这里包含有递归的思想,因此在后面的配置解析代码里可以看到某些函数被递归调用,其原因也就在这里。
对于复杂配置项来说,其值是由多个简单/复杂配置项组成,因此nginx不做过细的处理,一般就是申请内容空间、切换解析状态,然后递归调用解析函数;真正将用户配置信息转换为nginx内变量的值,还是那些简单配置项所对应的处理函数。3.配置项详细说明:
不管是简单配置项还是复杂配置项,他们的项目名和项目值都是由标记(token)组成。配置项目名就是一个token,而配置项目值可以使一个、两个、多个token组成。所谓标记(token):这里指一个配置文件字符串内容中被空格、引号、括号,比如’{‘、换行符等分割开来的字符子串。
举例说明:
比如简单配置项:daemon off;其项目名daemon为一个token,项目值off也是一个token。而简单配置项:error_page 404 /404.html;其项目值就包含有两个token,分别为404和/404.html。对于复杂配置项:location /www {index index.html index.htm index.php;}其项目名location为一个token,项目值是一个token(/www)和多条简单配置项组成的复合结构。
而如果我在配置文件内加入如下配置内容:
lenky on;
启动nginx,直接返回错误,这是因为对于lenky指令,nginx没有对应的代码去解析它:
[emerg]: unknown directive “lenky” in /usr/local/nginx/conf/nginx.conf:2
lenky on;
启动nginx,直接返回错误,这是因为对于lenky指令,nginx没有对应的代码去解析它:
[emerg]: unknown directive “lenky” in /usr/local/nginx/conf/nginx.conf:2
二、NGINX中结构体 与函数
对于Nginx而言,我们需要根据某些规则自己书写配置文件nginx.conf。那么nginx.conf中的指令及指令的取值在NGINX程序中是以何种形式呈现的呢?问题举例:即daemon on; 在NGINX程序中是如何体现的呢?
1.存放指令取值的结构体
在NGINX中有一类自定义的配置结构体,其格式具有统一的规则。
对于HTTP模块中:ngx_http_<module name>_(main|srv|loc)_conf_t对于EVENT模块:ngx_event_conf_t对于CORE模块:ngx_core_conf_t。
这类自定义的配置结构体的作用:
存放指令的取值。即NGINX在这些自定义的配置结构体中存放nginx.conf中的指令的取值。
举例:ngx_core_conf_t 的成员变量 ngx_flag_t daemon就是存放指令daemon的取值。
2. 存放指令的结构体
在Nginx中有一类统一的指令结构体ngx_commant_t。
在ngx_commant_t ngx_core_commands[]={
{指令A},
{指令B},
ngx_null_command
}
关于该指令结构体ngx_commant_t的解释
3. 与配置文件有关的函数
ngx_conf_parse和 ngx_conf_handler 可参阅http://lenky.info/2011/09/09/nginx%E9%85%8D%E7%BD%AE%E4%BF%A1%E6%81%AF%E7%9A%84%E8%A7%A3%E6%9E%90%E6%B5%81%E7%A8%8B-3/
三、配置文件解析的流程
1.总流程:
不管对于CORE MODULE or HTTP or EVENT MODULE,其主要流程如下所示:
1、某个void **ctx数组存放通过ngx_modules[i]->ctx->create_conf获得的ngx_xxx_conf_t结构体2.构造ngx_conf_t conf 。填写里面几个成员变量。void *ctx即为1.中ctx数组,即eg:conf.ctx = ctxngx_uint_t module_type 填写为CORE or HTTP or EVENT。eg:conf.module_type = NGX_CORE_MODULEngx_uint_t cmd_type 填写为MAIN or SERVER or LOCATION.eg:conf.cmd_type = NGX_MAIN_CONF3.调用ngx_conf_parse(ngx_conf_t conf ,xxx)函数,进行解析。在ngx_conf_handler函数中,void * conf通过ctx数组,获得某个特定token所处于的模块的ngx_xxx_conf_t结构体,即conf指向了某个特定token所处的结构体的位置。再指向cmd->set函数,从而可以将token的取值存入conf指向的某个特定token所处的结构体。从而完成token取值从配置文件到程序特定变量的过程。整体过程如上所述,详细过程还请依次阅读对于NGX_CORE_MODULE、NGX_EVENT_MODULE、NGX_HTTP_MODULE的分析。
2.详细过程
在ngx_init_cycle函数中
在ngx_conf_parse函数调用ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)函数
对于daemon而言
对于NGX_EVENT_MODULE而言
在ngx_events_block中
对于NGX_HTTP_MODULE
static char *
ngx_http_block (ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *rv;
ngx_uint_t mi, m, s;
ngx_conf_t pcf;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t **cscfp;
ngx_http_core_main_conf_t *cmcf;
/* the main http context */
/*1)
typedef struct {
void **main_conf;
void **srv_conf;
void **loc_conf;
} ngx_http_conf_ctx_t;
这儿的main_conf srv_conf loc_conf分别作为 http的main server location配置项的的ngx_xxx_conf_t的存放数组。
* */
ctx = ngx_pcalloc(cf-> pool, sizeof (ngx_http_conf_ctx_t));
if (ctx == NULL) {
return NGX_CONF_ERROR;
}
*(ngx_http_conf_ctx_t **) conf = ctx;
/* count the number of the http modules and set up their indices */
ngx_http_max_module = 0;
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}
ngx_modules[m]-> ctx_index = ngx_http_max_module++;
}
/* the http main_conf context, it is the same in the all http contexts */
ctx->main_conf = ngx_pcalloc(cf-> pool,
sizeof(void *) * ngx_http_max_module);
if (ctx-> main_conf == NULL) {
return NGX_CONF_ERROR;
}
/*
* the http null srv_conf context, it is used to merge
* the server{}s' srv_conf's
*/
ctx->srv_conf = ngx_pcalloc(cf-> pool, sizeof (void *) * ngx_http_max_module);
if (ctx-> srv_conf == NULL) {
return NGX_CONF_ERROR;
}
/*
* the http null loc_conf context, it is used to merge
* the server{}s' loc_conf's
*/
ctx->loc_conf = ngx_pcalloc(cf-> pool, sizeof (void *) * ngx_http_max_module);
if (ctx-> loc_conf == NULL) {
return NGX_CONF_ERROR;
}
/*
* create the main_conf's, the null srv_conf's, and the null loc_conf's
* of the all http modules
*/
/*2)通过循环所有模块,分别创建 http的main server location配置项的的ngx_xxx_conf_t,并且分别存入相应的数组*/
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}
module = ngx_modules[m]-> ctx;
mi = ngx_modules[m]-> ctx_index;
if (module->create_main_conf ) {
ctx-> main_conf[mi] = module->create_main_conf (cf);
if (ctx->main_conf [mi] == NULL) {
return NGX_CONF_ERROR;
}
}
if (module->create_srv_conf ) {
ctx-> srv_conf[mi] = module->create_srv_conf (cf);
if (ctx->srv_conf [mi] == NULL) {
return NGX_CONF_ERROR;
}
}
if (module->create_loc_conf ) {
ctx-> loc_conf[mi] = module->create_loc_conf (cf);
if (ctx->loc_conf [mi] == NULL) {
return NGX_CONF_ERROR;
}
}
}
/*
* 设置 cf 从而进行解析
cf-> ctx = ctx;
cf-> module_type = NGX_HTTP_MODULE;
cf-> cmd_type = NGX_HTTP_MAIN_CONF;
*
* */
pcf = *cf;
cf->ctx = ctx;
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}
module = ngx_modules[m]-> ctx;
/*
*在读入配置之前调用NGX_HTTP_MODULE的preconfiguration函数
* */
if (module->preconfiguration ) {
if (module->preconfiguration (cf) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
}
/* parse inside the http{} block */
cf->module_type = NGX_HTTP_MODULE;
cf->cmd_type = NGX_HTTP_MAIN_CONF;
rv = ngx_conf_parse(cf, NULL);
if (rv != NGX_CONF_OK) {
goto failed;
}
/*
* init http {} main_conf's, merge the server{}s' srv_conf's
* and its location{}s' loc_conf's
*/
/*
*从配置文件中读入配置,存入相应的自定义配置结构体ngx_http_<module name>_(main|srv|loc)_conf_t
* */
cmcf = ctx-> main_conf[ngx_http_core_module.ctx_index ];
cscfp = cmcf-> servers.elts ;
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}
module = ngx_modules[m]-> ctx;
mi = ngx_modules[m]-> ctx_index;
/* init http{} main_conf's */
if (module->init_main_conf ) {
rv = module-> init_main_conf(cf, ctx->main_conf [mi]);
if (rv != NGX_CONF_OK) {
goto failed;
}
}
rv = ngx_http_merge_servers(cf, cmcf, module, mi);
if (rv != NGX_CONF_OK) {
goto failed;
}
}
/* create location trees */
for (s = 0; s < cmcf-> servers.nelts ; s++) {
clcf = cscfp[s]-> ctx->loc_conf [ngx_http_core_module.ctx_index];
if (ngx_http_init_locations(cf, cscfp[s], clcf) != NGX_OK) {
return NGX_CONF_ERROR;
}
if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
if (ngx_http_init_phases(cf, cmcf) != NGX_OK) {
return NGX_CONF_ERROR;
}
if (ngx_http_init_headers_in_hash(cf, cmcf) != NGX_OK) {
return NGX_CONF_ERROR;
}
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}
module = ngx_modules[m]-> ctx;
/*
*在读入配置之前调用NGX_HTTP_MODULE的postconfiguration 函数
* */
if (module->postconfiguration ) {
if (module->postconfiguration (cf) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
}
if (ngx_http_variables_init_vars(cf) != NGX_OK) {
return NGX_CONF_ERROR;
}
/*
* http{}'s cf ->ctx was needed while the configuration merging
* and in postconfiguration process
*/
*cf = pcf;
if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) {
return NGX_CONF_ERROR;
}
/* optimize the lists of ports, addresses and server names */
if (ngx_http_optimize_servers(cf, cmcf, cmcf-> ports) != NGX_OK) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
failed:
*cf = pcf;
return rv;
}
1)http://lenky.info/2011/09/09/nginx%E9%85%8D%E7%BD%AE%E4%BF%A1%E6%81%AF%E7%9A%84%E8%A7%A3%E6%9E%90%E6%B5%81%E7%A8%8B-3/
- 文章20:NGINX配置文件格式及处理流程
- struts2项目配置文件及处理流程
- Nginx配置文件处理过程
- 原创:第二节struts1的处理流程及配置文件详解
- 第二节struts1的处理流程及配置文件详解
- Nginx配置文件及解释
- FreeSwitch全局配置文件处理流程
- Nginx简介及配置文件详解
- Nginx简介及配置文件详解
- Nginx简介及配置文件详解
- Nginx配置文件及代理服务器设置
- Nginx配置文件实例及说明
- Nginx简介及配置文件详解
- Nginx简介及配置文件详解
- Nginx简介及配置文件详解
- Nginx安装及配置文件nginx.conf详解
- Nginx安装及配置文件nginx.conf详解
- Nginx安装及配置文件nginx.conf详解
- NoSql数据库的安装与使用
- OpenCv1.0入门(一)-基本数据结构和头文件
- 选择适合你的虚拟现实体验
- Oracle创建用户、表空间、导入导出、...命令
- 【phpcms-v9】phpcms-v9中栏目页的静态化生成
- 文章20:NGINX配置文件格式及处理流程
- 最近写出一个bug,关于模块在注册时返回-1
- Mac OS X下搭建Android开发环境(包括SDK和NDK)
- IOS开发之──应用之间调用(1)
- 面向对象之类的设计_代码大全笔记(二)
- 如何快速正确的安装 Ruby, Rails 运行环境 [ 转!很好 ]
- vb做的excel小软件
- YII+DWZ,SESSION超时后采用DWZ的弹窗登陆模式
- 打包