美文网首页
Nginx的location指令配置

Nginx的location指令配置

作者: ligang1109 | 来源:发表于2018-02-20 15:57 被阅读86次

    http://blog.7rule.com/2018/02/20/nginx-location.html

    在编写nginx配置中,正确的配置location指令是相当重要的。笔者在一次问题的排查中仔细研究了下这个指令的规则和使用方法,在这里和大家分享一下,如有不正确的地方还望指正。

    指令语法

    location [ 限定符 ] 规则uri { 指令集 }

    在一个请求的处理流程中,nginx会启动一个location的查找过程,在这个过程中nginx会根据一定的规则用请求的request_uri有选择的去匹配这些定义好的规则uri,之后会找到要应用的唯一的location,并应用这个location定义的指令集中的指令。

    这里面最关键的地方,就是location的查找过程是如何进行的。要明白这个过程,首先需要知道规则uri是如何定义的。

    规则uri

    规则uri分为三种类型,nginx对这几种类型执行的匹配方法是不同的:

    1. 对限定符为=的规则执行完全匹配

    完全匹配例:location = index.php {},那么仅有请求:http://domain/index.php才能匹配,http://domain/index.phpphttp://domain/iindex.php这种均无法匹配。

    2. 对限定符为^~或没有限定符规则执行前缀匹配。

    前缀匹配例:location /abc {}或location ^~ /abc {},那么请求:http://domain/abcdhttp://domain/abc.php这种均能匹配。

    3. 对限定符为~~*的规则执行正则匹配。

    正则匹配例:location ~ .php$ {},那么请求:http://domain/abc.phphttp://domain/abcd.php这种均可以匹配。

    location的查找过程

    首先会对所有的等号规则前缀规则进行一次匹配筛选。nginx会在所有的前缀匹配中找到一个最长的匹配,然后记住这个匹配的location。之后会根据这个匹配规则是否有限定符来决定之后的行为:

    1. 如果是等号规则匹配到的,nginx会立即结束查找过程,这个location就是最终结果。

    2. 如果匹配到的规则被限定符^~修饰,则nginx也会结束这个查找过程,这个location就是最终结果。

    3. 如果没有找到匹配或是匹配项没有被限定符修饰,nginx就会进入正则规则的匹配筛选过程。在这个过程中,nginx会按照规则uri在配置中定义的顺序来进行匹配,只要匹配到其中一个,nginx就会立即结束这个匹配过程,这个location也会是最终location。如果没有能找到一个正则匹配,但是之前的前缀匹配成功,那么之前记住的前缀匹配结果则会成为最终结果。

    通过上面的查找过程,如果成功找到匹配的location,则会执行执行这个location定义的指令集中的指令。

    实例说明

    下面举几个例子来看一下:假设用户均访问http://www.vmc7.com/abc

    1. =命中,跳过正则匹配

    server {
        listen 80;
    
        server_name www.vmc7.com;
    
        location /abc {}
    
        location = /abc {}
    
        location ~ /abc {}
    }
    

    2. ^~命中,跳过正则匹配

    server {
    
        listen 80;
    
        server_name www.vmc7.com;
    
        location /ab {}
    
        location ^~ /abc {}
    
        location ~ /abc {}
    }
    

    3. 正则命中1,正则匹配优先于前缀匹配

    server {
        listen 80;
    
        server_name www.vmc7.com;
    
        location /abc {}
    
        location ~ /ab.* {}
    }
    

    4. 正则命中2,正则按顺序匹配

    server {
        listen 80;
    
        server_name www.vmc7.com;
    
        location /ab {}
    
        location ~ /ab.* {}
        location ~ /abc {}
    }
    

    5. 前缀命中,正则匹配不到,使用之前命中的前缀匹配

    server {
        listen 80;
    
        server_name www.vmc7.com;
    
        location /abc {}
    
        location ~ /ef.* {}
    }
    

    最后附上伪代码用以描述整个过程

    location = findLocation();
    if (location != null) {
        runLocationCmdSet();
    }
     
    function findLocation()
    {
        finalLocation  = null;
        prefixLocation = null;
        regexLocation  = null;
     
        prefixLocation = findByPrefix();
        if (prefixLocation != null) {
            if (preceding(prefixLocation) == '=') {
                return prefixLocation;
            }
    
            if (preceding(prefixLocation) == '^~') {
                return prefixLocation;
            }
        }
     
        regexLocation = findByRegex();
        finalLocation = (regexLocation == null) ? prefixLocation : regexLocation;
     
        return finalLocation;
    }
     
    function findByPrefix()
    {
        result    = null;
        maxLength = 0;
     
        for (location in allPrefixLocation) {
            if ((matchLength = prefixMatch(location))!= 0) {
                if (matchLength > maxLength) {
                    maxLength = matchLength;
                    result    = location;
                }
            }
        }
     
        return result;
    }
     
    function findByRegex()
    {
        for (location in allRegexLocation) {
            if (regexMatch(location)) {
                return location;
            }
        }
     
        return null;
    }
    

    相关文章

      网友评论

          本文标题:Nginx的location指令配置

          本文链接:https://www.haomeiwen.com/subject/duegtftx.html