首页 > 代码库 > 【Nginx】HTTP配置模型
【Nginx】HTTP配置模型
当Nginx检测到配置文件中存在配置块http{}时,会建立一个ngx_http_conf_ctx_t结构体,该结构体定义如下:
typedef struct { void **main_conf; // 每个指针元素指向所有由HTTP模块的create_main_conf方法产生的结构体 void **srv_conf; // 每个指针元素指向所有由HTTP模块的create_srv_conf方法产生的结构体 void **loc_conf; // 每个指针元素指向所有由HTTP模块的create_loc_conf方法产生的结构体 } ngx_http_conf_ctx_t;
具体来说,框架代码在遇到http{}时会调用核心模块ngx_http_module(HTTP框架的一部分)中解析配置项的ngx_http_block方法,该方法的关于生成和配置ngx_http_conf_ctx_t结构体的过程大致如下,代码位于ngx_http.c中:
ngx_http_conf_ctx_t *ctx; // 定义一个该结构体的指针 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); // 分配该结构体空间 ctx->main_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); // 分配数组存放指针 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); // 分配数组存放指针 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); // 分配数组存放指针 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) { /* 依次调用所有HTTP模块的create_main_conf方法 * 产生的结构体指针放入上面分配了空间的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) { /* 依次调用所有HTTP模块的create_srv_conf方法 * 产生的结构体指针放入上面分配了空间的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) { /* 依次调用所有HTTP模块的create_loc_conf方法 * 产生的结构体指针放入上面分配了空间的loc_conf指针数组中 */ ctx->loc_conf[mi] = module->create_loc_conf(cf); if (ctx->loc_conf[mi] == NULL) { return NGX_CONF_ERROR; } } }
server{}和location{}和http{}相似:
- 当遇到server{}配置块时,建立ngx_http_conf_ctx_t结构体,main_conf成员指向父配置块所对应的ngx_http_conf_ctx_t结构体,srv_conf成员和loc_conf成员存储HTTP模块通过create_srv_conf和create_loc_conf方法产生的配置结构体指针。
- 当遇到location{}配置块时,建立ngx_http_conf_ctx_t结构体,main_conf成员指向父配置块对应ngx_http_conf_ctx_t结构体,srv_conf成员指向父配置块ngx_http_conf_ctx_t结构体的srv_conf元素,loc_conf存储HTTP模块create_loc_conf方法产生的配置结构体指针。
三个ngx_http_conf_ctx_t结构体分别对应http{}、server{}、location{},它们之间的关系用下图可以清晰的说明:
下面介绍解析HTTP配置的大致流程:
- Nginx进程主循环调用配置文件解析器解析nginx.conf配置文件。
- 配置文件解析器发现http{},启动HTTP框架,也就是核心模块ngx_http_module。
- 核心模块调用ngx_command_t中的set回调函数,也就是ngx_http_block方法。
- 初始化所有HTTP模块的序号,分配一个ngx_http_conf_ctx_t结构体并初始化三个数组。
- 调用每个HTTP模块的create_main_conf、create_srv_conf、create_loc_conf方法分配存储配置项参数的结构体,返回的指针保存在ngx_http_conf_ctx_t结构体中。
- 调用每个HTTP模块的preconfiguration方法。
- 配置文件解析器检测到一个配置项后,遍历所有HTTP模块的ngx_command_t数组,看有没有能够和配置项名称匹配的ngx_command_t结构体,有则调用ngx_command_t结构中的set方法来处理配置项。
- 配置文件解析器继续检测配置项,遇到server{}或location{}则以类似的方法递归解析块中的配置项,不过此时负责解析配置项的模块变成了ngx_http_core_module,方法在上面已经详细说明了。
- 配置文件解析器解析到http{}尾端,返回HTTP框架ngx_http_module。
- 调用merge_srv_conf和merge_loc_conf等方法合并配置项结构体。
- HTTP框架处理完http配置项,ngx_command_t的set回调方法返回。
- 配置文件解析器返回Nginx主循环,Nginx进程启动Web服务器。
参考:
《深入理解Nginx》 P140-P143.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。