程序员

Nginx指令阶段和常见错误总结

2020-08-25  本文已影响0人  小a草
Nginx指令阶段

因为nginx执行是按阶段执行的,我们一般的程序都是按顺序执行的。nginx指令一般是分布在不同阶段的;
Nginx 处理请求的过程一共划分为 11 个阶段,按照执行顺序依次是 post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、try-files、content 以及 log.

// eg:
server {
    listen 8080;
    set_real_ip_from 127.0.0.1;
    real_ip_header   X-My-IP;

    location /test {
        set $addr $remote_addr;
        echo "from: $addr";
    }
}
// eg:
server {
    listen 8080;

    location /test {
        set $b "$a, world";
        echo $b;
    }

    set $a hello;
}
location /hello {
    echo "hello world";
}
// eg
server {
    listen 8080;

    location /test {
        set_real_ip_from 127.0.0.1;
        real_ip_header X-Real-IP;

        echo "from: $remote_addr";
    }
}

与先看前到的例子相比,此例最重要的区别在于把 ngx_realip 的配置指令放在了 location 配置块中。前面我们介绍过,Nginx 匹配 location 的动作发生在 find-config 阶段,而 find-config 阶段远远晚于 post-read 阶段执行,所以在 post-read 阶段,当前请求还没有和任何 location 相关联。

// eg1
location /test {
    try_files /foo /bar/ /baz;
    echo "uri: $uri";
}
// eg2
location /test {
    try_files /foo /bar/ =404;
    echo "uri: $uri";
}
// eg1
location /test {
    satisfy all;
    deny all;
    access_by_lua 'ngx.exit(ngx.OK)';
    echo something important;
}
// eg2
location /test {
    satisfy any;
    deny all;
    access_by_lua 'ngx.exit(ngx.OK)';
    echo something important;
}
nginx中邪恶的if指令

if指令用来判断条件为true时要执行的指令,条件false时不执行相应的指令,if指令只能用在server、location内。
因为nginx执行是按阶段执行的,我们一般的程序都是按顺序执行的。nginx指令一般是分布在不同阶段的;

// 不推荐配置
server {
    server_name example.com *.example.com;
        if ($host ~* ^www\.(.+)) {
            set $raw_domain $1;
            rewrite ^/(.*)$ $raw_domain/$1 permanent;
        }
        # [...]
    }
}
// 推荐
server {
    server_name www.example.com;
    return 301 $scheme://example.com$request_uri;
}
server {
    server_name example.com;
}

// 不推荐配置
server {
    root /var/www/example.com;
    location / {
        if (!-f $request_filename) {
            break;
        }
    }
}
// 推荐配置
server {
    root /var/www/example.com;
    location / {
        try_files $uri $uri/ /index.html;
    }
}
费力的 rewrites

rewrite 很容易和正则表达式混为一谈。 实际上,rewrite 是很容易的,我们应该努力去保持它们的整洁。

// 不推荐
rewrite ^/(.*)$ http://example.com/$1 permanent;
// 好一些
rewrite ^ http://example.com$request_uri? permanent;
// 更好些
return 301 http://example.com$request_uri;

忽略 http:// 的 rewrite

// 不推荐
rewrite ^ example.com permanent;
// 推荐
rewrite ^ http://example.com permanent;

没有使用标准的 Document Root Location

server {
    root /;
    location / {
        try_files /web/$uri $uri @php;
    }
    location @php {
    }
}
nginx配置的常见陷阱
server {
        server_name www.example.com;
        location / {
            root /var/www/Nginx -default/;
            # [...]
          }
        location /foo {
            root /var/www/Nginx -default/;
            # [...]
        }
  }

正确案例

server {
        server_name www.example.com;
        root /var/www/Nginx -default/;
        location / {
            # [...]
        }
        location /foo {
            # [...]
        }
}
http {
    index index.php index.htm index.html;
    server {
        server_name www.example.com;
        location / {
            index index.php index.htm index.html;
        }
    }
    server {
        server_name example.com;
        location / {
            index index.php index.htm index.html;
        }
        location /foo {
            index index.php;
        }
    }
}

正确案例

http {
    index index.php index.htm index.html;
    server {
        server_name www.example.com;
        location / {
        }
    }
    server {
        server_name example.com;
        location / {
        }
        location /foo {
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读