上一篇文章分析了nginx.conf配置解析流程,解析完成后会把各个配置项存放到各个模块的上下文结构中。但此时还没有对http模块、server模块、location模块公共部分进行合并处理。所谓的合并: server块的模块上下文没有值,则继承http模块的模块上下文值。location块的模块上下文没有值,则继承server块模块上下文的值。接下来分析nginx是如何合并http模块、server模块、location模块公共部分。

假设nginx.conf配置文件结构如下

http
{   //server块1server{//location块1location{}//location块2location{}}//server块2server{}
}

这是nginx.conf配置文件的一个框架结构,其中省略了其他配置项。http模块下有两个server块。其中第一个server块下还有两个location块。解析配置后,http模块的上下文结构如下图:

http块下有两个server块,分别为server块1,server块2。这两个server块是通过数组形式连接起来。http块中的main_conf[0]核心模块上下文结构为ngx_http_core_main_conf_t,它的成员servers就是一个数组,存放这这两个server块。

ngx_http_core_loc_conf_s结构中的成员locations是一个队列,队列元素为某个server块下的各个location结构。图中server块1下有两个location块,server1块loc_conf中的核心模块上下文结构的ocations,是由这两个location块组成的队列。

也就是说server块是通过数组串接起来的, location块是通过链表串接起来的。

一、http块与server块的合并

http块与server块的合并过程分析:包含server块的合并,location块的合并。

(1)server块的合并: 对于每一个模块,在每一个server块中,找到模块在srv_conf中的位置,然后将该模块上下文与http块中srv_conf对应模块所在位置模块上下文进行比较。如果server块中的上下文没有值,则使用http上下文的值,否则使用server块中模块上下文自己的值。以ngx_core_module模块为例,这个模块是第一个模块,存放在srv_conf下标为0的位置。首先将server1块中的srv_conf[0]与http块的srv_conf[0]进行合并, 然后将server2块中的srv_conf[0]与http块的srv_conf[0]进行合并。这样server块的合并就完成了。

(2)location块的合并: 对于每一个模块,在每一个server块中,找到模块在loc_conf中的位置,然后将该模块上下文与http块中loc_conf对应模块所在模块上下文进行比较。如果location块中的上下文没有值,则使用http上下文中的值,否则使用location块中模块上下文自己的值。以ngx_core_module模块为例,这个模块是第一个模块,存放在loc_conf下标为0的位置。首先将server1块中的loc_conf[0]与http块的loc_conf[0]进行合并, 然后将server2块中的lco_conf[0]与http块的loc_conf[0]进行合并。这样loc块的合并就完成了。

char * ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{for (m = 0; ngx_modules[m]; m++) {if (ngx_modules[m]->type != NGX_HTTP_MODULE) {continue;}//(1)将http中的server与server块的server合并//(2)将http中的loction与server块的location合并//(3)将server块中的location与localtion中的location合并rv = ngx_http_merge_servers(cf, cmcf, module, mi);}
}

而其中的函数ngx_http_merge_servers负责具体的合并过程。这个函数一共使用了3个合并过程,先分来http块与server的合并。

//cmcf = ctx->main_conf[ngx_http_core_module.ctx_index],其中ctx是http块的ngx_http_conf_ctx_t结构
//module指的是模块上下文
//ctx_index指的是该模块在同一类型中的位置
static char * ngx_http_merge_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,ngx_http_module_t *module, ngx_uint_t ctx_index)
{//cscfp指向所有http块下的所有server块cscfp = cmcf->servers.elts;//ctx指向http块的ngx_http_conf_ctx_t结构ctx = (ngx_http_conf_ctx_t *) cf->ctx;  //遍历http块下有所有server块for (s = 0; s < cmcf->servers.nelts; s++) {//指向每一个server块中的srv_conf结构ctx->srv_conf = cscfp[s]->ctx->srv_conf;if (module->merge_srv_conf) {//将http块中的某个server与server块中的某个server进行合并//saved.srv_conf[ctx_index]是http块下的srv_conf中某个元素//cscfp[s]->ctx->srv_conf[ctx_index]是server块下的srv_conf中某个元素rv = module->merge_srv_conf(cf, saved.srv_conf[ctx_index], cscfp[s]->ctx->srv_conf[ctx_index]);}if (module->merge_loc_conf) {ctx->loc_conf = cscfp[s]->ctx->loc_conf;//将server块中loc_conf的某个loc与http块中loc_conf的某个loc合并rv = module->merge_loc_conf(cf, saved.loc_conf[ctx_index],  cscfp[s]->ctx->loc_conf[ctx_index]);}}
}

二、server块与location块的合并
        server块与location块合并的内容就比较少了,只需要将各个location块中的loc_conf与server块中的loc_conf进行合并。

location块的合并: 对于每一个模块,在每一个location块中,找到模块在loc_conf中的位置,然后将该模块上下文与所属server块中loc_conf对应模块所在模块上下文进行比较。如果location块中的上下文没有值,则使用所属server块上下文中的值,否则使用location块中模块上下文自己的值。以ngx_core_module模块为例,这个模块是第一个模块,存放在loc_conf下标为0的位置。首先将location1块中的loc_conf[0]与server块1的loc_conf[0]进行合并, 然后将locatio2块中的lco_conf[0]与server1块的loc_conf[0]进行合并。这样loc块的合并就完成了。


        函数ngx_http_merge_locations负责server块与location块的合并。当然如果location还嵌套location块,则会递归合并location块与location内的所有子locaton块。

//locations为server块中ngx_http_core_module的lociton中队列
//loc_conf为server块的loc_conf
//module为模块上下文
//ctx_index指module对应模块在同一类模块中的索引
static char * ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations,void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index)
{for (q = ngx_queue_head(locations);q != ngx_queue_sentinel(locations);q = ngx_queue_next(q)){//合并server块与locatin块中相应的location//loc_conf[ctx_index]为server块中loc_conf的某个loc//clcf->loc_conf[ctx_index]为location块中的loc_conf的某个locrv = module->merge_loc_conf(cf, loc_conf[ctx_index], clcf->loc_conf[ctx_index]);//递归合并location块下的location//clcf->locations为location块中的loc_conf某个loc对应的队列//clcf->loc_conf为location块中的loc_confrv = ngx_http_merge_locations(cf, clcf->locations, clcf->loc_conf, module, ctx_index);}
}

最终ngx_core_module模块的合并结果如下:


        以上只是ngx_core_module模块的合并结果,其它模块合并的过程也是一样的。最终一个for循环,就可以合并所有http模块。这样每一个http模块的上下文结构都有值,这个值要么来自nginx.conf配置文件,要么继承上一层结构。

nginx配置解析之配置合并相关推荐

  1. Spring AOP 源码系列(一)解析 AOP 配置信息

    在进行源码阅读之前建议先看一下这篇文章:Spring AOP 源码分析系列文章导读 by 田小波,写的非常好,推荐阅读. 关于 AOP 中常用的一些术语这里就不解释了,如果不清楚的建议先看一遍上面推荐 ...

  2. 运维之DNS服务器Bind9配置解析和基础示例及附带命令

    0x03 Bind 配置解析 实例1.DNS主从区域传输介绍与配置 实例2.DNS区域传输限制 实例3.DNS部分二级域名解析 示例1.采用Bind建立一个A记录DNS服务器 示例2.采用Bind建立 ...

  3. linksys无线打印服务器,Linksys无线路由 详细配置解析

    02Linksys无线路由 详细配置解析 详细配置解析 设置 首次登陆进入 首先我们在地址栏输入Linksyssmartwifi.com 进入路由器,我们进去进行首次配置路由器,第一次进去我们可以选择 ...

  4. nginx配置解析流程

    上一篇文章分析了nginx配置文件缓冲区的管理,接下来将详细分析nginx是如何解析配置文件的.包含模块上下文结构的创建.core核心模块的解析.event事件模块的解析.http模块的解析. 一.模 ...

  5. nginx html解析插件,nginx配置信息的解析流程

    nginx配置信息的解析流程 2011年9月9日 1,744 次浏览 请关注最新修正合订: 这一系列的文章还是在09年写的,存在电脑里很久了,现在贴出来.顺序也不记得了,看到那个就发那个吧,最近都会发 ...

  6. 三、nginx服务的nginx.conf的参数配置解析

    前一篇:二.nginx服务的nginx.conf配置参数解析 后一篇:四.nginx服务器的参数配置解析 目录 一.虚拟主机设定模块 1.upstream模块配置样式 1.1.默认配置 1.2.wei ...

  7. nginx配置解析之缓冲区管理

    nginx服务器的master进程在解析nginx.conf时,会使用一个4k大小的缓存区存放部分配置文件信息.nginx会从配置文件中读取4k大小的内容到缓冲区,之后对缓冲区中的内容进行逐个字符扫描 ...

  8. nginx基础概念及配置解析

    nginx入门与实战 网站服务 想必我们大多数人都是通过访问网站而开始接触互联网的吧.我们平时访问的网站服务 就是 Web 网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务. Web ...

  9. NGINX负载均衡配置解析

    课程目标 掌握什么是负载均衡及负载均衡的作用和意义. 了解lvs负载均衡的三种模式. 了解lvs-DR负载均衡部署方法. 掌握nginx实现负载均衡的方法. 掌握lvs+nginx负载均衡拓扑结构. ...

最新文章

  1. 以太网未识别的网络win10_工业以太网典型应用、常见故障、冗余网络技术及实例...
  2. 轻知 | 为什么全球只有13组根域名服务器?
  3. Maven入门:使用Nexus搭建Maven私服及上传下载jar包
  4. node.js服务端代码学习
  5. [转]Linux内核基础与常用命令总结
  6. O-超大型LED显示屏
  7. 2M口,电口,光口的区别
  8. 自然语言处理理论与实战
  9. 【情感识别】基于matlab支持向量机(SVM)语音情感识别【含Matlab源码 543期】
  10. Abelssoft Undeleter(数据恢复软件)v5.01免费版
  11. iphone win7无法识别_win7系统电脑插入苹果设备提示“无法识别IOS设备”的原因和解决方法...
  12. 他安息,只因天使离去
  13. MPEG音频文件格式(包括MP3文件格式)详解
  14. jQuery实现打字小游戏
  15. 送女朋友实用的七夕礼物、送女朋友七夕礼物最有意义排行榜
  16. 大写汉字(大写汉字又称什么数码)
  17. 每位开发人员都应铭记的10句编程谚语
  18. Vue常用的组件库大全【前端工程师必备】【实时更新】【移动端、PC端(web端)、数据可视化组件库(数据大屏) 、动画组件库、3D组件库】
  19. 免费SVN代码托管,不限私有,不限成员
  20. MySQL运维进阶必备

热门文章

  1. 营收净利涨超60%,吉比特凭借《摩尔庄园》赶超完美世界?
  2. JavaScript性能优化8——防抖与节流
  3. 亚马逊计划裁员 1 万人,创公司史上纪录
  4. 离婚时才知道丈夫年入300万,丈夫藏的是真够深的
  5. C++实验一之CMatrix类设计与实现
  6. 语音之家SOTA | TIOBE 场景测试:电台节目 张震鬼故事
  7. web手势库AlloyFinger运用( 控制CANVAS中图片移动、缩放、旋转) - 可编辑图片指定区域位置
  8. 常用的文本标签都有哪些呢?
  9. 我的第一次实质性开源贡献——Apache IoTDB
  10. ffmpeg视频压缩速度_使用ffmpeg修改视频速度