Nginx配置继承模型

Nginx的配置是一大特色。可以类比css文件中样式的定义,子元素会继承父元素的样式定义并可以选择是否覆盖,nginx配置中同样存在类似的继承关系。(我这样子想但不一定准确)

翻译自UNDERSTANDING THE NGINX CONFIGURATION INHERITANCE MODEL

为理解nginx配置的继承模型,你需要知道nginx配置有好几个块,一个块也被称为一个上下文(context),例如在server上下文中定义的指令存放在server{}块中,http上下文中定义的指令存放在http{}块中。

在nginx中存在6种可能的上下文,顺序从高到低依次是:

  • Global
  • Http
  • Server
  • If
  • Location
    • Nested Location
    • if in location
    • limit_except

默认的继承模型方向是低层继承高层,而不是横向或逆向。一个常见的场景是,重写请求从一个location内部跳转到另一个location,那么在第一个location块中定义的指令就会被忽略,而只有第二个location块中定义的指令在location context中有效。

按继承行为分,nginx配置指令可分为四种:

  • Normal directive:每个context中只有一个值,ie:root、index
  • Array directive:每个context可有多个值,ie:access_log,fastcgi_param
  • Action directive:不只是配置,ie:rewrite、fastcgi_pass
  • try_files

Normal directive是目前最一般的一种,遵循默认的继承模型,看个例子(本文例子与原文有些差别):

server{
	root /home/gao/nginx/public_html;
	
	location /app {
		root /home/gao/nginx/share; #覆盖掉server中root的配置
                                #结果存放在路径/home/gao/nginx/share中,
                                  #完整的URI添加到root之后
                                #比如请求127.0.0.1/app/hello.html,则会返
                          # 回/home/gao/nginx/share/app/hello.html文件
	}

	location /app2 {
                                        #继承server中root的配置
                                        #如果请求127.0.0.1/app2/hello.html,
                                  # 则会返回/home/gao/nginx/public_html/app2/hello.html文件
	}
}

Array directive很像Normal directive,也遵循默认的继承模型。可能令人迷惑的是这些指令假定你把值添加到列表中,而不是简单赋值,如果你在同一个context中定义多个相同的指令,那么这些指令值会连接在一起,而如果你在不同级的context中定义多个相同的指令,那么低层context中的定义会覆盖掉高层次中的定义。例子:

server{
	root /home/gao/nginx/public_html;
	access_log /home/gao/nginx/logs/access1.log;

	
	location /app {
		root /home/gao/nginx/share;

		access_log /home/gao/nginx/logs/access2.log;

		access_log /home/gao/nginx/logs/access3.log;
	}
}
    #在例子中若访问/app开头的URL,则访问日志记录在access2.log和access3.log中,而不会存到
    #access1.log中,其他的URL访问日志记录在access1.log中

Action directives是个有趣的地方,它们只限于一个context中,不会进行继承。如果在多级context中都进行指定,那么在每个context中都会执行。rewrite就是一个这样的指令,允许在server context和location context中指定,可能在每个context中都会执行。

server{
	
	rewrite ^/booking(.*) /app$1 permanent;#总是执行

	location /app {
		rewrite ^ /index.html;#与server context rewrites互不干扰
	}
}

但也没这么简单,在location context中有三种可能的context,nested location,if,limit_except。active 指令的具体行为实际上完全依赖于模块是怎样定义的。对normal directives和array directives会在允许的context中恰当地继承,而对active directives情况就有点不同。通常它们不会通过继承传递到嵌套的location context中,而是完全依赖于module的实现,而且对不同的指令,行为也可能不同。ngix文档这时也没什么用处,你只能去尝试,看nginx如何反应。下面是一个例子:

    server{			
	location /share {
		rewrite ^ /index.html;#如果内部嵌套的location匹配就不会执行
		
		location ~ \.html$ {
			rewrite ^ /50x.html; #外部的rewrite不会执行
		}
	}
}
    #在这个例子中只要开头为/share的URL以.html结尾就显示/50x.html,否则显示/index.html

try_files指令与其他active directive类似,区别是如果放在server context中nginx会创建一个伪location以承接所有没有匹配的请求,即这个伪location为最不精准最泛的一个匹配,相当于定义了location /,那么所有的请求都会被匹配(最差也能匹配location /),而如果请求与一个location匹配,try_files就不会执行,所以尽可能不要把try_files放在server context中。

server {
    try_files $uri /index.php; # This never executes.

    location / {
        # Whatever here, or empty.
    }

    location ~ \.php$ {
        # If this location executes then try_files still does not execute.
        # Even if location / did not exist.
    }
}

转载于:https://my.oschina.net/7gaoxing/blog/109846

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值