43 | 冲突的配置指令以谁为准?
http配置指令的一个嵌套结构,很多http模块提供的指令很多时候它可以出现在的context(上下文)。可以在location中、server中、http中,甚至在if这样的配置块中。当一个指令出现在多个配置块中的时候,它们可能值是冲突的。到底以谁为准呢?或者说在有些配置块下,没有这条指令,但是在使用的过程中发现它生效了,这是怎样的机制呢?还有很多第三方模块不是非常的遵循官方模块既定的一些规则。这个时候应该怎样判断配置指令时怎么生效或者说发生冲突以谁为准呢?
配置块典型的嵌套
image.pnghttp、server、location这三个是非常核心的。这是http的框架来定义的。我们处理一个请求的时候,需要先按照请求中的指示的域名,比如host,找到相应的server块,再根据uri找到每一个location,根据location下面具体的指令来处理请求。在这么一个典型的配置块的配置中,我们会发现冲突或者奇怪的指令。
指令的Context
image.png图中的Context就是作用范围。如果把log_format 放到了server中,nginx检查配置文件语法失败,不会让我们启动。
指令的合并
值指令、动作类指令
image.png怎么判断一个指令到底是可以合并还是不可以合并呢?就是很简单,生效阶段。
server_rewrite与rewrite 阶段,只有http rewrite模块才会提供。content阶段一般是反向代理。这一部分(第三部分)的课程会介绍到5个content模块,这些content模块通常提供了一些方法只能是动作类指令的。当然还可以通过源码判断出来。相对来说动作类指令不是很多。
存储值的指令继承规则:向上覆盖
image.pnglisten这个指令只能出现在server这个context中。alias指令可以出现在很多地方server中,http中。上图中只在location中出现了。当一个请求匹配上/dlib
时,alias就产生作用了。
需要我们考虑值合并的场景。比如图中定义了一个root指令,查找静态文件到/home/geek/nginx/html
中查找,但是在location /
匹配剩余的url时并没有定义root,但是它可以使用server中定义的root指令。这里就是子配置不存在时,直接使用父配置块
。
图中location /test
里定义了一个root跟access_log。子配置存在时,直接覆盖父配置块
。
HTTP模块合并配置的实现
所有nginx的官方模块或者openresty的一些nginx模块,它们都遵循上面的两个合并规则。但是有一些第三方模块没有遵循这个规则。如果相应的说明文档不是非常详细的话,就需要我们通过源码来判断。当它们的子指令出现冲突的时候,究竟以哪个为准。怎么通过源码来判断。抓住下面四个点:
image.png大部分指令都是在location中生效的。
当这个指令在server块生效的时候,会定义一个方法merge_srv_conf。这个指令即出现在http下又出现在server下,从http向server合并的时候会提供一个函数merge_srv_conf。如果是在location下生效那么就是merge_loc_conf。下面以http referer(用来做防盗链)为例。
在这个模块中(或者任何一个模块)都会有这样的一个结构体ngx_module_t。
image.png这个模块提供的配置的指令全部在ngx_command_t数组中。
image.png这个数组中每一个元素就是一条指令。比如:valid referers,它允许出现在那一块下面呢?NGX_HTTP_SRV_CONF、NGX_HTTP_LOC_CONF
,可以携带几个参数呢?一个或多个——NGX_CONF_1MORE
。所有的指令解析完以后可能要做合并,比如http、server、location进行合并。合并的时候要看下面的一个结构体。
ngx_http_module_t定义了可能出现的8个回调方法。特别是最后两个ngx_http_referer_create_conf、ngx_http_referer_merge_conf。重点看merge_conf。因为以上所说的指令都是在location中生效的,所以需要把http、sever下的向location这些地方合并。在这个合并方法中就可以看到规则(下图)。
image.png第二个参数parent就是父指令,child就是子指令 。它们合并的方法都可以看得到的。
image.png简单介绍了http模块指令的合并规则,为下面讲解每一个http模块的用法提供了基础的帮助。
课后留言
1.不可以合并的指令发生冲突时是怎么处理的呢?课程中只讲了可以合并的指令行为
作者回复
合并中,父子冲突时,以子配置为准
网友评论