Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

nginx 配置之 location 优先级

  我以前觉得 CSS 选择器的优先级已经挺复杂的了,但仔细了解 nginx location 指令的优先级后发现它简直要复杂几条街!现在我们只介绍最简单最常用的几个语法的优先级。而且这仅仅是优先级本身而已,很多奇怪的指令还会对 location 指令的计算产生影响,带来更复杂的结果。
  其实 nginx 的 locaiton 指令的匹配顺序并不是简单地把优先级和修饰符对应起来的,所以我们很难完全用「优先级」的概念来描述 locaiton 指令的匹配顺序。
  首先,最先匹配的是「绝对匹配」,也就是用「=」作为修饰符的匹配。如果非要以优先级来说的话,它就是优先级最高的。比如下面这样
location = /index.html { # ... }   然后,与「绝对匹配」对应的就是部分匹配,它分为两大类。一类是「前缀匹配」,另一类是「正则匹配」。前缀匹配有两种形式,一种是以「^~」作为修饰符,另一种是空修饰符(它们都不区分大小写)。正则匹配也有两种形式,分别是「~」(区分大小写)和「~*」(不区分大小写)。
  对于「前缀匹配」之间的匹配顺序比较是根据匹配到的字符数量来定的,匹配到的字符数量越多就越优先。而正则匹配之间的优先级则是以它们定义的先后顺序来决定的,越先定义的优先级越高。
  当解析开始时,所有同类的匹配之间先做比较,最后可以得到一个「前缀匹配」和一个「正则匹配」的结果(可能只有其中一种),然后再对这两类匹配做一个比较。如果最终的「前缀匹配」是使用「^~」修饰符定义的,那么它将优先于「正则匹配」,否则反之。
  下面是一个典型的例子,猜一猜如果 $uri 是 /abcde 的话将得到什么结果?
location ^~ /ab { return 200 ab; } location ~ a { return 200 a; } location /abc { return 200 abc; }   首先,我们来看看「前缀匹配」的处理结果。由于前缀匹配是根据字符数量决定优先级的,所以 /abc 的优先级高于 ^~ /ab,最终匹配的是 /abc。然后「正则匹配」只有一个,所以最终的结果就是 ~ a。之后再拿这两个最终结果做比较,由于最终的「前缀匹配」结果并没有使用 ^~ 定义,所以 ~ a 的优先级更高,所以最终将使用 return 200 a; 作为配置。
  假如配置这么写呢?也就是把最后一个 location 去掉,结果又会如何?
location ^~ /ab { return 200 ab; } location ~ a { return 200 a; }   根据上面的计算规则,易得出最终使用的是 return 200 ab; 这个配置。
  在上面的两个例子中,location /abc 始终没有被匹配到,但它确影响了另外两个 location 的结果。所以说,nginx 的 location 处理顺序无法简单地使用优先级来描述。
  以上这些真的只是基础的,实际上就 location 的处理顺序问题还有很多纠结的地方呢!
网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^