在这一篇文章里,我将先容nginx关于location的处理惩罚,各人都知道Nginx设置文件内里会有许多的location,nginx的设置指令的浸染域可以分为 main,server,location这3个种,实际上这3者不是依次包括的干系,而是彼此独立的干系,好比一个只具有main级别浸染域的指令,是不能写在某个server可能location内的,模块的某个指令可以同时具有main,server,location这3种浸染域,别的每个模块有 main,srv,loc这3个级此外设置,一个模块的main级此外设置对所有的server和location都是共享的,srv级此外设置对所有 location都是共享的,location只有本身独立的loc级此外设置,这就是为什么一个模块的srv和loc级此外设置需要merge,而 main级此外设置不需要merge的原因。这里看起来有点绕,区分一下main,server,location别离作为一种浸染域级别和一个主体,雷同于形容词和名字的区别,nginx的设置干系照旧不难领略的。
一般来说一个请求url过来,nginx会将它理会到某一个location来处理惩罚。这个理会的进程实际上按照location的设置根基可以分为字符串匹配和正则表达式匹配这2种。对付location的组织方法,最简朴的就是直接将它们生存为一个链表,理会url的时候一个一个遍历即可找到相应location,可是这样效率太低,对像nginx这种高机能的处事器来说是完全不行取的,nginx将字符串匹配的location组织成了一个三叉的字符串排序树,并且成立的时候也思量了树的均衡性。文章后头我讲具体先容源码的实现。
首先我来或许的先容一下location的种类和匹配法则,以nginx wiki(http://wiki.nginx.org/HttpCoreModule#location)的例子做说明:
location = / {
# matches the query / only.
[ configuration A ]
}
location / {
# matches any query, since all queries begin with /, but regular
# expressions and any longer conventional blocks will be
# matched first.
[ configuration B ]
}
location ^~ /images/ {
# matches any query beginning with /images/ and halts searching,
# so regular expressions will not be checked.
[ configuration C ]
}
location ~* .(gif|jpg|jpeg)$ {
# matches any request ending in gif, jpg, or jpeg. However, all
# requests to the /images/ directory will be handled by
# Configuration C.
[ configuration D ]
}
location @named {
# Such locations are not used during normal processing of requests,
# they are intended only to process internally redirected requests (for example error_page, try_files).
[ configuration E ]
}
可以看到上面的例子中有5种差异范例的location,个中第4个带 “~” 号前缀的为需要正则匹配的location,nginx在举办url理会时对这5种差异范例的location具有差异的优先级法则,大抵的法则如下:
1,字符串准确匹配到一个带 “=” 号前缀的location,则遏制,且利用这个location的设置;
2,字符串匹配剩下的非正则和非非凡location,假如匹配到某个带 "^~" 前缀的location,则遏制;
3,正则匹配,匹配顺序为location在设置文件中呈现的顺序。假如匹配到某个正则location,则遏制,并利用这个location的设置;不然,利用步调2中获得的具有最大字符串匹配的location设置。
譬喻,对下面的请求有:
1, / -> 准确匹配到第1个location,匹配遏制,利用configuration A
2,/some/other/url -> 首先前缀部门字符串匹配到了第2个location,然后举办正则匹配,显然没有匹配上,则利用第2个location的设置configurationB
3,/images /1.jpg -> 首先前缀部门字符串匹配到了第2个location,可是接着对第3个location也前缀匹配上了,并且这时已经是设置文件内里对这个url的最大字符串匹配了,而且location带有 "^~" 前缀,则不再举办正则匹配,最终利用configuration C
4,/some/other/path/to/1.jpg -> 首先前缀部门同样字符串匹配到了第2个location,然后举办正则匹配,这时正则匹配乐成,则利用congifuration D