Nginx命令,匹配规则

前端 0 482 0
发表于: 2020-02-24 15:48:58

简介: 暂无~

常用命令

nginx 启动nginx

nginx -v 查看nginx版本

nginx -t 测试配置文件语法正确性

nginx -s stop 快速关闭Nginx,可能不保存相关信息,并迅速终止web服务

nginx -s quit 平稳关闭Nginx,保存相关信息,有安排的结束web服务

nginx -s reload 重新载入nginx,当配置信息修改需要重新加载配置是使用

taskkill /fi “imagename eq nginx.EXE” /f window下杀掉所有nginx进程

location

匹配规则

符号 说明
~ 正则匹配,区分大小写
~* 正则匹配,不区分大小写
^~ 和无修饰符类似,但是如果有^~,一旦匹配到就终止匹配
= 普通字符匹配,精确匹配
无修饰符,根据前缀匹配

匹配优先级顺序

1、nginx首先检查基于前缀的location匹配(即不包含正则表达式的匹配)

2、如果有使用=修饰符的location块与请求的URL完全匹配,则立刻使用该location响应请求

3、如果没有找到带有=修饰符的location块匹配,则会继续计算非精确前缀,根据给定的URI找到最长匹配前缀,举个例子,nginx有/static和/static/js两个匹配路径,浏览器请求/static/js/aaa,这个路径都是/static前缀和/static/js/前缀,但是会选最长的/static/js/,然后保存起来

4、判断保存的location带不带 ^~,如果带有 ^~,则使用该location,并不再继续匹配,如果没有带 ^~,则继续匹配

5、在确定并储存最长匹配的前缀location块后,nginx继续检查正则表达式匹配location(区分大小写/不区分大小写),如果存在正则表达式满足要求的匹配,则会选择与请求的URI匹配的第一个正则表达式的location来相应请求

5、如果没有找到与请求的URI匹配的正则表达式location,则使用之前存储的最长前缀location响应请求

注意

通常情况下,一旦选择使用某一个location响应请求,那么请求将会在该location内部进行处理,而与其他location无关.但是location中某些指令会触发新的location匹配,比如:

(1)try_files

(2)rewrite

(3)error_page

匹配的顺序是先匹配普通字符串,然后再匹配正则表达式

另外普通字符串匹配顺序是根据配置中字符长度从长到短,也就是说使用普通字符串配置的location顺序是无关紧要的,反正最后nginx会根据配置的长短来进行匹配,但是需要注意的是,正则表达式按照配置文件里的顺序匹配。找到第一个匹配的正则表达式将停止搜索

匹配顺序案例

location / {
    default_type application/json ;
    return 200  '{"name":"/","result":"/-success"}';
}


location /gethome1 {
    default_type application/json ;
    return 200  '{"name":"gethome1","result":"gethome1-success"}';
}

location /gethome {
    default_type application/json ;
    return 200  '{"name":"gethome","result":"gethome-success"}';
}

location ^~ /gethome100 {
    default_type application/json ;
    return 200  '{"name":"^~ /gethome100","result":"^~ /gethome100-success"}';
}

上面的匹配顺序优先级: ^~ /gethome100 > /gethome1 > /gehome> /,优先级和书写顺序无关。

如果地址栏上输入/gethome,先精准匹配,没有=,继续前缀匹配,找到/gethome1,/gethome,^~ /gethome100,但只有/gethome是/gethome的前缀,因此保存/gethome,继续后面的正则匹配,但是后面没有了,因此最终就是匹配到/gethome

如果地址栏上输入/gethome1,先精准匹配,没有=,继续前缀匹配,找到/gethome1,/gethome,^~ /gethome100,其中/gethome1和/gethome都是/gethome1的前缀,保存最长的,因此保存/gethome1,继续后面的正则匹配,但是后面没有了,因此最终就是匹配到/gethome1

如果地址栏上输入/gethome100,先精准匹配,没有=,继续前缀匹配,找到/gethome1,/gethome,^~ /gethome100,这三个都是/gethome100的前缀,保存最长的,因此保存/gethome100,而且/gethome100前面有^~前缀,直接使用这个匹配结果,不再继续匹配。

如果地址栏上输入/gethome100123,先精准匹配,没有=,继续前缀匹配,找到/gethome1,/gethome,^~ /gethome100,这三个都是/gethome100123的前缀,保存最长的,因此保存/gethome100,而且/gethome100前面有^~前缀,直接使用这个匹配结果,不再继续匹配。

#location /gethobby {
#    default_type application/json ;
#    return 200  '{"name":"gethome","result":"gethome-success"}';
#}

location ^~ /gethobby { # location ^~/gethobby 空格不影响
    default_type application/json ;
    #return 状态码 数据
    return 200  '{"name":"^~/gethobby","result":"^~/gethobby-success"}';
}

location ^~ /gethobby100 { # location ^~/gethobby100 空格不影响
    default_type application/json ;
    #return 状态码 数据
    return 200  '{"name":"^~/gethobby100","result":"^~/gethobby100-success"}';
}

nginx不能同时写两个 /gethobby 和 ^~ /gethobby,否则会报错:nginx: [emerg] duplicate location “/gethobby”

匹配结果:

当浏览器地址栏输入:/gethobby时候,会匹配到^~ /gethobby

当浏览器地址栏输入:/gethobby123时候,会匹配到^~ /gethobby

当浏览器地址栏输入:/gethobby100时候,会匹配到^~ /gethobby100

当浏览器地址栏输入:/gethobby100123时候,会匹配到^~ /gethobby100

普通字符匹配和^~普通字符匹配区别

location / {
    default_type application/json ;
    return 200  '{"name":"/","result":"/-success"}';
}

location ^~ /static {
    default_type application/json ;
    return 200  '{"name":"static","result":"static-success"}';
}

location ~ (jpg|jpeg|png|gif|mp3|mp4)$ {    #匹配以jpg|jpeg|png|gif|mp3|mp4结尾的路径
    default_type application/json ;
    return 200  '{"name":"正则匹配区分大小写","result":"正则匹配区分大小写-success"}';
}

地址栏:/static/musicmp3,先匹配 ^~ /static,命中匹配,不会继续匹配下面的正则,结果就是匹配到^~ /static

地址栏:/static/musicmp5,先匹配 ^~ /static,命中匹配,不会继续匹配下面的正则,结果就是匹配到^~ /static

location / {
    default_type application/json ;
    return 200  '{"name":"/","result":"/-success"}';
}

location /static {
    default_type application/json ;
    return 200  '{"name":"static","result":"static-success"}';
}

location ~ (jpg|jpeg|png|gif|mp3|mp4)$ {    #匹配以jpg|jpeg|png|gif|mp3|mp4结尾的路径
    default_type application/json ;
    return 200  '{"name":"正则匹配区分大小写","result":"正则匹配区分大小写-success"}';
}

地址栏:/static/musicmp3,先匹配 /static,命中匹配,继续匹配下面的正则,命中~ (jpg|jpeg|png|gif|mp3|mp4)$,则结果就是匹配到~ (jpg|jpeg|png|gif|mp3|mp4)$

地址栏:/static/musicmp5,先匹配 /static,命中匹配,继续匹配下面的正则,不符合~ (jpg|jpeg|png|gif|mp3|mp4)$,则结果就是匹配到/static

关于loalhost后面的/

当location后面有/时

server {
    listen 90;
    server_name localhost;
    
    location / {
        default_type application/json ;
        return 200  '{"name":"测试/","result":"测试/-success"}';
    }
    
    location /test/ {
        default_type application/json ;
        return 200  '{"name":"测试test","result":"测试test-success"}';
    }
}

浏览器输入http://127.0.0.1:90/test时,匹配到/,匹配不到/test/

浏览器输入http://127.0.0.1:90/test/时,匹配到/test/,匹配不到/

浏览器输入http://127.0.0.1:90/test/aaa时,匹配到/test/,匹配不到/

浏览器输入http://127.0.0.1:90/testaaa时,匹配到/,匹配不到/test/

浏览器输入http://127.0.0.1:90/test/aaa/aaa时,匹配到/test/,匹配不到/

当location后面没有/时

server {
    listen 90;
    server_name localhost;
    
    location / {
        default_type application/json ;
        return 200  '{"name":"测试/","result":"测试/-success"}';
    }

    location /test {
        default_type application/json ;
        return 200  '{"name":"测试","result":"success"}';
    }
}

浏览器输入http://127.0.0.1:90/test时,匹配到/test,匹配不到/

浏览器输入http://127.0.0.1:90/test/时,匹配到/test,匹配不到/

浏览器输入http://127.0.0.1:90/test/aaa时,匹配到/test,匹配不到/

浏览器输入http://127.0.0.1:90/testaaa时,匹配到/test,匹配不到/

浏览器输入http://127.0.0.1:90/test/aaa/aaa时,匹配到/test,匹配不到/

location /chat {
    proxy_pass http://localhost:5001;
}

http://localhost/chat ===> http://localhost:5001/chat

http://localhost/chat/ ===> http://localhost:5001/chat

http://localhost/chat/chat ===> http://localhost:5001/chat/chat

location /chat {
    proxy_pass http://localhost:5001/;
}
# ===> proxy_pass + 原url匹配的location路径之后的内容

http://localhost/chat ===> http://localhost:5001/

http://localhost/chat/ ===> http://localhost:5001//

http://localhost/chat/chat ===> http://localhost:5001//chat

结论

当location后面有/时,只能访问test/ 以及test/xxx等路径。

当location后面没有/时,可以访问test开头的任意路径。

proxy_pass

在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径,会把匹配到的路径部分去掉(即不带到代理地址上)

如果没有/,表示相对路径,把匹配的路径部分也给代理走(即把匹配到的部分也带到代理地址上)。

监听5001端口

server {
    listen       5001;
    server_name  localhost;
    gzip on;
    # 进行压缩的文件类型。
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    # 是否在http header中添加Vary: Accept-Encoding,建议开启
    gzip_vary on;
    location / {
        default_type application/json ;
        return 200  '{"name":"5001/","result":"5001/-success"}';
    }
    location /xxx {
        default_type application/json ;
        return 200  '{"name":"5001/xxx","result":"5001/xxx-success"}';
    }
    location /xxx/ {
        default_type application/json ;
        return 200  '{"name":"5001/xxx/","result":"5001/xxx/-success"}';
    }

}

监听5002端口

server {
    listen       5002;
    server_name  localhost;
    gzip on;
    # 进行压缩的文件类型。
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    # 是否在http header中添加Vary: Accept-Encoding,建议开启
    gzip_vary on;
    location / {
        default_type application/json ;
        return 200  '{"name":"5002/","result":"5002/-success"}';
    }

    location /xxx {
        proxy_pass http://localhost:5001;
    }
    location /xxx/ {
        proxy_pass http://localhost:5001;
    }
}

proxy_pass末尾没有斜杠

5001端口

server {
        listen       5001;
        server_name  localhost;
		gzip on;
	    # 进行压缩的文件类型。
	   	gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
	    # 是否在http header中添加Vary: Accept-Encoding,建议开启
	    gzip_vary on;
		location / {
            default_type application/json ;
            return 200  '{"name":"5001/","result":"5001/-success"}';
        }
        location /xxx {
            default_type application/json ;
            return 200  '{"name":"5001/xxx","result":"5001/xxx-success"}';
        }
        location /xxx/ {
            default_type application/json ;
            return 200  '{"name":"5001/xxx/","result":"5001/xxx/-success"}';
        }
        location /yyy {
            default_type application/json ;
            return 200  '{"name":"5001/yyy","result":"5001/yyy-success"}';
        }
        location /aaa {
            default_type application/json ;
            return 200  '{"name":"5001/aaa","result":"5001/aaa-success"}';
        }
        location /yyy/aaa {
            default_type application/json ;
            return 200  '{"name":"5001/yyy/aaa","result":"5001/yyy/aaa-success"}';
        }
        location /aaa/yyy {
            default_type application/json ;
            return 200  '{"name":"5001/aaa/yyy","result":"5001/aaa/yyy-success"}';
        }

    }

5002端口

server {
    listen       5002;
    server_name  localhost;
    gzip on;
    # 进行压缩的文件类型。
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    # 是否在http header中添加Vary: Accept-Encoding,建议开启
    gzip_vary on;
    location / {
        default_type application/json ;
        return 200  '{"name":"5002/","result":"5002/-success"}';
    }

    location /xxx {
        proxy_pass http://localhost:5001;
    }
    location /xxx/ {
        proxy_pass http://localhost:5001;
    }
    location /yyy {
        proxy_pass http://localhost:5001/aaa;
    }
    location /aaa {
        proxy_pass http://localhost:5001/aaa/yyy;
    }
}

浏览器地址栏:http://localhost:5002/xxx或者http://localhost:5002/xxx123,匹配到nginx中5002端口的/xxx(因为/xxx是/xxx的前缀,不是/xxx/的前缀,因为少了一个/),然后匹配到的该路径又代理到了5001端口,且没有带/,即相对路径,会将/xxx带给http://localhost:5001,实际代理到:http://localhost:5001/xxx

浏览器地址栏:http://localhost:5002/xxx/或者http://localhost:5002/xxx/123,匹配到nginx中5002端口的/xxx/(因为/xxx和/xxx/都是/xxx的前缀,但取最长的/xxx/),然后匹配到的该路径又代理到了5001端口,且没有带/,即相对路径,会将/xxx/带给http://localhost:5001,实际代理到:http://localhost:5001/xxx/

浏览器地址栏:http://localhost:5002/yyy,匹配到nginx中5002端口的/yyy,注意,此时虽然proxy_pass的URL最后没有带/,但是,它有URI,因此不能把/yyy带到这个URL的后面,不能匹配到http://localhost:5001/aaa/yyy,也不会匹配到:http://localhost:5001/yyy/aaa,只能匹配到:http://localhost:5001/aaa

浏览器地址栏:http://localhost:5002/aaa,匹配到nginx中5002端口的/aaa,注意,此时虽然proxy_pass的URL最后没有带/,但是,它有URI,因此不能把/aaa带到这个URL的后面,不能匹配到http://localhost:5001/aaa/yyy/aaa,也不会匹配到:http://localhost:5001/aaa/aaa/yyy,只能匹配到:http://localhost:5001/aaa/yyy

proxy_pass末尾有斜杠

5002端口

server {
    listen       5002;
    server_name  localhost;
    gzip on;
    # 进行压缩的文件类型。
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    # 是否在http header中添加Vary: Accept-Encoding,建议开启
    gzip_vary on;
    location / {
        default_type application/json ;
        return 200  '{"name":"5002/","result":"5002/-success"}';
    }

    location /xxx {
        proxy_pass http://localhost:5001/;
    }
    location /xxx/ {
        proxy_pass http://localhost:5001/;
    }
    location /yyy {
        proxy_pass http://localhost:5001/aaa/;
    }
    location /aaa {
        proxy_pass http://localhost:5001/aaa/yyy/;
    }
}

浏览器地址栏:http://localhost:5002/xxx或http://localhost:5002/xxx123,匹配到nginx中5002端口的/xxx(因为/xxx是/xxx的前缀,不是/xxx/的前缀,因为少了一个/),然后匹配到的该路径又代理到了proxy_pass http://localhost:5001/,且带了/,即绝对路径,最终就是代理到http://localhost:5001/

浏览器地址栏:http://localhost:5002/xxx/或http://localhost:5002/xxx/123,匹配到nginx中5002端口的/xxx/(因为/xxx和/xxx/都是/xxx的前缀,但取最长的/xxx/),然后匹配到的该路径又代理到了proxy_pass http://localhost:5001/,且带了/,即绝对路径,最终就是代理到http://localhost:5001/

浏览器地址栏:http://localhost:5002/yyy或http://localhost:5002/yyy123或http://localhost:5002/yyy/123,匹配到nginx中5002端口的/yyy,然后匹配到的该路径又代理到了proxy_pass http://localhost:5001/aaa/,且带了/,即绝对路径,最终就是代理到http://localhost:5001/aaa/

浏览器地址栏:http://localhost:5002/aaa或http://localhost:5002/aaa123或http://localhost:5002/aaa/123,匹配到nginx中5002端口的/aaa,然后匹配到的该路径又代理到了5001端口,且带了/,即绝对路径,最终就是代理到http://localhost:5001/aaa/yyy/

小结

实际应用时,localtion最后最好加/

server {
 listen       5001;
 server_name  localhost;
 location /api/ {
     proxy_pass http://localhost:5002/;
 }
}

http://localhost:5001/api/ ===> http://localhost:5002

localtion加/的好处是,只有/api/才可以匹配,如果不加/,就只是/api,那样/api123,/api456等等都可匹配到/api,有很多可能性都可以匹配到/api,因此最好就加/,那样只有/api/123,/api/456/等等可以匹配到/api/。

而下面的proxy_pass,最好只是URL,不要带URI,而最后加不加/就看需求,比如我希望http://localhost:5001直接代理到http://localhost:5002,那么设置location /,proxy_pass是http://localhost:5002/,这样http://localhost:5001就会直接匹配到http://localhost:5002

那么,假设我服务器的3000端口被nuxt项目占了,而我这个nuxt项目里又要用到3003端口的数据,那么我nuxt项目(3000端口)要如何获取到3003端口的数据呢,这里就可以在nginx的3000端口添加一条路径,localtion为/,proxy_pass http://localhost:3003/,这样就会将http://localhost:3000代理到http://localhost:3003

但是,因为我的nuxt项目是在443端口的,443端口的localtion /就是代理到我的nuxt项目3000端口,那么这时候就不能使用/来代理到3003了,因此可以换成localtion /api/,proxy_pass不变,这样443端口匹配到/api/就会代理到http://localhost:3003,在nuxt项目里设置请求的前缀都是/api/即可

location /chat/ {
    proxy_pass http://localhost:5001/;
}
# http://localhost/chat/  ===> http://localhost:5001/
location /chat/ {
    proxy_pass http://localhost:5001/webchat/;
}
# http://localhost/chat/  ===> http://localhost:5001/webchat/

参考

https://blog.csdn.net/agonie201218/article/details/92795522

https://juejin.cn/post/6844903796791836685#heading-3

https://blog.csdn.net/qq_33862644/article/details/79337348

https://blog.csdn.net/xiaoxiangzi520/article/details/78737527

https://blog.csdn.net/zwl18210851801/article/details/81699977

nginx

最后更新于:2022-04-25 22:14:00

欢迎评论留言~
0/400
支持markdown
Comments | 0 条留言
按时间
按热度
目前还没有人留言~