nginx知识点整理

1 location 路径

1.1 四个优先级

=^~~(或~*)、直接字符串。

# 1
location =/a/b/c{
    echo "=/a/b/c 等于,最高优先级";
}

# 2
location ^~/a/b{
    echo "^~/a/b /a/b开头的,次高优先级";
}

# 3 注意$和`{`间要空开,不然会认为是变量
location ~^/\w/\w/\w$ {
    echo "正则,第三优先级";
}

# 4
location /a{
    echo "/a /a开头的,优先级最低"
}

判定规则:

规则1测试:

image

规则2测试:

添加配置

# 5
location ^~/a/b/d{
    echo "^~/a/b/d /a/b/d开头的,次高优先级";
}

同样进行上述四个url的测试,结果出现细微差别,如下,证明了同一级别是匹配程度越高的生效

image

规则3测试:

添加配置:

# 6
location ~^/\d/\d/\d$ {
    echo "d数字正则";
}
# 7
location ~^/[0-9]/[0-9]/[0-9]$ {
    echo "0-9数字正则";
}

1.2 路径中的/

location /a{
    proxy_pass http://ip;
}
location /b/{
    proxy_pass http://ip/;
}

效果:

2 http相关参数

内置的变量参考http://nginx.org/en/docs/http/ngx_http_core_module.html#arg_name,这里列出最常用的

1 $http_xxx  请求头中xxx字段如$http_content_type,注意下划线与小写
2 $arg_xxx   路径中的查询参数xxx,如$arg_username
3 $request_method 请求方法如“GET

3 变量与正则

if ( $host ~* (.*)\.(.*)\.(.*)\.(.*) ) {
    set $myport $1;
}
proxy_pass http://192.168.0.12:$myport;

4 负载均衡

upstream group1{
    server 192.168.0.12:80;
    server 192.168.0.12:81;
}
server{
    ....
    location /f {
        proxy_pass http://group1;
    }
}

默认的分配策略是轮流来↓。

image

修改策略:

5 rewrite与proxy_pass

两者都用于跳转,rewrite跳转指定匹配的路径和新的路径,proxy_pass代理。rewrite通过正则可以实现proxy_pass,但是做代理proxy_pass写法更简单。

这里主要介绍下rewrite:

rewrite   <regex>   <replacement>   <flag>;

flag四种形式:

last或不写:跳转后继续匹配其他location
break:终止匹配 
redirect:302临时重定向,浏览器地址跳转(不写域名则端口会变成80)
permanent:301永久重定向,浏览器地址跳转(端口会变成80

对以下配置进行测试:

location /re{
    if(arg_a){
        rewrite ^ /a/b/c;
    }
    if(arg_b){
        rewrite ^ /a/b/d break;
    }
    if(arg_c){
        rewrite ^ http://192.168.0.12:82/a/b redirect;
    }
    if(arg_d){
        rewrite ^ http://192.168.0.12:82/a/x permanent;
    }
}

测试结果如下:
image

其中break那一条是404,因为跳转后不再匹配了,一般用于转到静态文件,或者其他域名。

6 运行周期

nginx的运行周期分为11个阶段(有点多)。

- post-read:     读取请求内容
- server-rewrite:写在server范围内的rewrite执行
- find-config:   寻找符合条件的location
- rewrite:       写在location范围内的rewrite执行
- post-rewrite:  rewrite执行完成
- pre-access:    访问检查前
- access:        访问检查
- post-access:   访问检查后
- try-files:     try-files配置项执行
- content:       内容输出阶段
- log:           记录日志

你可能会有疑问,问啥有几个阶段要分别记录xx前/xx时/xx后,这是因为有些插件的执行时机是要在这些关键时间节点的。举个例子:比如使用了access_by_lua,则这部分代码是在access阶段进行的,如果有个请求对用户名密码进行了编码,而因为历史原因不能在这部分代码修改。则可以使用其他插件在pre-access阶段进行解码处理。

从几个阶段中,我们可以看出最重要的三个部分是:rewrite、access和content。这三个部分在lua插件中也分别对应了rewrite_by_lua、access_by_lua和content_by_lua。关于更多插件的使用将会在下一篇openresty中讲解。