Nginx的location规则迷之匹配

Nginx,一个改变世界的软件,其作者是一个俄罗斯人,俗称毛子,在国人的印象中,是一群晚饭后牵着大灰熊在小区楼下散步的彪汉。能写出这般顺滑的软件,可谓是心有猛虎细嗅蔷薇典型代表啊。
很多同学都被location规则绕得云里雾里,总是搞不清楚自己写的规则为什么没有生效。其实location复杂的匹配规则可以用一句话来概括——女生想用最省力的方法找合适的男生。好像更云里雾里了,且听我娓娓道来。

网上一些对location认识的误区我就不写在这里混淆视听了,直接写我认为是对的,而且确实是对的规则。

对于非正则匹配,nginx会检索完所有的非正则location条目,而正则匹配,nginx会在匹配到第一条正则后,停止检索。为什么被设计成这样?上文提到女生想用最省力的方法找合适的男生,计算机检索非正则匹配是非常轻松的,所以它会把非正则的所有条目都看完,而计算机检索正则匹配的时候,会进行大量的逻辑运算,这样很不省力,违背了nginx为高效而生的初衷,所以被设计为检索到第一条能匹配的正则就停止检索。这就说明了location 的执行逻辑跟 location 在配置文件里面的编辑顺序是有关系的。
上面的话换个说法:
Nginx服务器会首先会检查多个location中是否有普通的uri匹配,如果有多个匹配,会先记住匹配度最高的那个。然后再检查正则匹配,这里切记正则匹配是有顺序的,从上到下依次匹配,一旦匹配成功,则结束检查,并就会使用这个location块处理此请求。如果正则匹配全部失败,就会使用刚才记录普通uri匹配度最高的那个location块处理此请求。

女生视角总结来说:她们会把那些条件比写得比较明确清晰的男生全都看完,找到一个最合适的做备胎(非正则匹配),然后她们会去看一眼那些条件看起来比较好,但写得比较模糊的,比如说就写了个某某公司总经理(正则匹配)一找到有合适的,则选之,不会再继续看那些后面的,若看完这些总经理都没找到合适的,用备胎。此时如果你头顶上有北上广本地土著的光环"^~",则会优先考虑。若你"="万达王公子,前面一切皆可抛啊。

总之;匹配优先规则如下:

➤优先级最高的是带有”=“修饰符的location区段,当请求的URI与指定的字符串精确匹配时,则nginx应用此段配置,不再看其他区段,女生视角来说,就是你刚好是王公子了。

➤第二优先级为带有"^~"的location区段,匹配到了“普通location ”后,不再需要继续匹配“正则location ”了,(^ 表示“非”,~ 表示“正则”,字符意思是:不要继续匹配正则)。女生视角来说,你是上海本地户口。

➤第三优先级为能匹配上的第一条正则匹配。女生视角来说,虽然你资料只写了个总经理,但颜值还不错,身高两米六。

➤第四优先级为不带修饰符的location区段,也就是普通字符串匹配。女生视角来说,前面那些正则都是画大饼的,还是去找备胎吧。

修饰符 说明
=
王公子
URI的定位必须与指定的模式精确匹配。该模式在这里限定为一个简单的文本字符串,不能使用正则表达式:
location = /abcd
这个配置语句:
能匹配上 https://hqidi.com/abcd (严格匹配)
能匹配上 https://hqidi.com/abcd?param1&param2 (不管查询字符串参数)
不能匹配 https://hqidi.com/abcd/ (结尾斜杠)
不能匹配 https://hqidi.com/abcde (在指定的模式后添加额外的字符)
^~
上海土著
可以理解为禁止贪婪匹配,因为正常的匹配规则是匹配到字符串后(=号匹配除外),还不死心,还得去看看正则有没有能匹配上的,加上"^~"前缀后,匹配到字符串后就应用本条规则,不再去看正则。
~* 不区分大小写的正则匹配。
location ~* ^/abcd$
这个配置语句:
能匹配上 https://hqidi.com/abcd (严格匹配)
能匹配上 https://hqidi.com/ABCD
能匹配上 https://hqidi.com/abcd?param1&param2 (不管查询字符串参数)
不能匹配 https://hqidi.com/abcd/(因为指定了正则表达式)
不能匹配 https://hqidi.com/abcde(额外字符,正则不匹配)
~ 客户端请求的URI与指定的正则表达式匹配必须区分大小写。
location ~ ^/abcd$
这个配置语句:
能匹配上 https://hqidi.com/abcd (严格匹配)
不能匹配 https://hqidi.com/ABCD (区分大小写)
不能匹配 https://hqidi.com/abcd/(因为指定了正则表达式)
不能匹配 https://hqidi.com/abcde(额外字符,正则不匹配)
(无) 当匹配前缀是空的时候,URI的定位必须以指定模式开始,不可以使用正则表达式。
location /abcd
这个配置语句:
能匹配上 https://hqidi.com/abcd (严格匹配)
能匹配上 https://hqidi.com/abcd?param1&param2 (不管查询字符串参数)
能匹配上 https://hqidi.com/abcd/ (结尾斜杠)
能匹配上 https://hqidi.com/abcde (在指定的模式后添加额外的字符)
@ @是一个命名标记,这种location不会用于正常的请求,它们通常只用于处理内部的重定向(例如:error_page,try_file)

nginx location实验部分

为了更清晰的说明实验,我用到了一个第三方的nginx模块"echo-nginx-module",模块安装请参考https://hqidi.com/82.html
主要配置文件如下:

#1
                    location  /abcd {
echo "现在匹配到的是 location  /abcd";
}

#2
                    location ~* /abcd {
echo "现在匹配到的是 location ~* /abcd";
}

#3
		    location ~ /abcd {
echo "现在匹配到的是 location ~ /abcd";
}

#4  
                    location ~ /abc {
echo "现在匹配到的是 location ~ /abc";
}

#5
                    location ^~ /abc {
echo "现在匹配到的是 location ^~ /abc";

#6
                    location = /abcd {
echo "现在匹配到的是 location = /abcd";
}

当配置文件如上所示时:

匹配到了带“=”号前缀的location区段,所以得出结论,当请求的URI与指定的字符串精确匹配时,“=”区段的匹配优先级最高。
现在把“=”区段注释掉,接着实验

[root@hqidi vhosts]# sed -i '27,$s/^/#/' location 
[root@hqidi vhosts]# cat !$
cat location
#1
                    location  /abcd {
echo "现在匹配到的是 location  /abcd";
}

#2
                    location ~* /abcd {
echo "现在匹配到的是 location ~* /abcd";
}

#3
		    location ~ /abcd {
echo "现在匹配到的是 location ~ /abcd";
}

#4  
                    location ~ /abc {
echo "现在匹配到的是 location ~ /abc";
}

#5
                    location ^~ /abc {
echo "现在匹配到的是 location ^~ /abc";
}

#6
#                    location = /abcd {
#echo "现在匹配到的是 location = /abcd";
#}
[root@hqidi vhosts]# r /usr
/usr/local/nginx/sbin/nginx -s reload

当配置文件如上所示时:

这里,有同学就会有疑问了,这不对啊,这不应该是匹配到带有本地土著光环的"^~"段吗?原来,他的优先级虽然高于正则匹配,但低于空前缀(location /abcd)的精确匹配,当我们请求https://hqidi.com/abcd 时,先会被"location /abcd"匹配上,前面说过,仅仅字符串匹配上,它还是不死心的,还会去按配置文件中出现的顺序进行正则匹配。为了验证这个说法,我们把第二和第三区段换个位置:

#1
                    location  /abcd {
echo "现在匹配到的是 location  /abcd";
}


#3
		    location ~ /abcd {
echo "现在匹配到的是 location ~ /abcd";
}

#2
                    location ~* /abcd {
echo "现在匹配到的是 location ~* /abcd";
}
#4  
                    location ~ /abc {
echo "现在匹配到的是 location ~ /abc";
}

#5
                    location ^~ /abc {
echo "现在匹配到的是 location ^~ /abc";
}

当配置文件如上所示时:

剔除干扰项,再次验证:

#1
#                    location  /abcd {
#echo "现在匹配到的是 location  /abcd";
#}


#3
		    location ~ /abcd {
echo "现在匹配到的是 location ~ /abcd";
}

#2
                    location ~* /abcd {
echo "现在匹配到的是 location ~* /abcd";
}
#4  
                    location ~ /abc {
echo "现在匹配到的是 location ~ /abc";
}

#5
                    location ^~ /abc {
echo "现在匹配到的是 location ^~ /abc";
}

当配置文件如上所示时:

可以看出土著光环生效了。
这个"^~",一般用于控制静态文件:
location ^~ /static/ {
root /webroot/static/;
}
如果你要强行用于动态文件:

 location ~ .*\.(php|php5)?$
        {
                fastcgi_pass  127.0.0.1:9000;
                fastcgi_index index.php;
                include fastcgi.conf;
        }

        location ^~ /test/ {    #因为^~的优先级比~高,当访问test/1.php,将被此段匹配到
                # rules
        }

结果就是php文件不会被解析。

接着实验

#1
                    location  /abcd {
echo "现在匹配到的是 location  /abcd";
}


#3
		    location ~ /abcd {
echo "现在匹配到的是 location ~ /abcd";
}

#2
                    location ~* /abcd {
echo "现在匹配到的是 location ~* /abcd";
}
#4  
                    location ~ /abc {
echo "现在匹配到的是 location ~ /abc";
}

#5
#                    location ^~ /abc {
#echo "现在匹配到的是 location ^~ /abc";
#}

当配置文件如上所示时:

客户端请求https://hqidi.com/abcd的时候,"location /abcd"这个区段其实先被规则匹配到,不过规则查找并没有停止,继续去查找有没有能匹配上的正则,如果有,就使用该正则匹配,并停止正则检索。
匹配优先级验证完毕,最后看一个最长匹配是什么鬼,最长匹配在女生视角很好理解,她们总是喜欢长的。。。最长匹配其实很简单,就是看起来最像的优先匹配。

          location ^~ /images/ {
echo "现在匹配到的是^~ /images/";
        }
          location /images/1/ {
echo "现在匹配到的是/images/1/";
        }

当配置文件如上所示时:

最后,希望看完的你没晕。。

原创文章转载请注明:Nginx的location规则迷之匹配 | 笛声博客

若你觉得本文对你有帮助,请博主喝一杯卡布奇板蓝根吧

原创文章,转载请注明: 转载自笛声

本文链接地址: Nginx的location规则迷之匹配

88 条评论

  • 姜辰 2017年8月5日 回复

    专业!高深!我决定还是用apache。

    • dige 2017年8月5日 回复 作者

      apache性能也是完全够的,只要不用IIS就行了。

      • 姜辰 2017年8月5日 回复

        在linux用IIS,那是什么赶脚~~哈哈~PHP,我个人比较喜欢apache,但是服务器内存小也只能nginx了~= =

        • 迎風别葉index 2018年2月24日 回复

          啊,在Linux用IIS是什操作,简直。。。。
          不过倒是看到很多在windows上要跑php用nginx或者用apache的,性能差的不是一点,搞不懂怎么想的

          • 云顶天的博客 2018年8月26日

            可能是觉得windows用起来习惯一些吧~

      • 姜辰 2019年10月9日 回复

        我用nginx一年了,但是这些。。。。还是不会。

        有啥规则,都是拿apache的转过来。= =、

  • 自媒体博客 2017年8月5日 回复

    虽然不懂,但是得顶!

  • 纬八路随笔 2017年8月5日 回复

    写的太高深,支持写作、分享。

  • 张戈 2017年8月26日 回复

    最佩服你这种钻研精神,nginx我虽然比较熟,这些匹配规则还是有一个模糊的经验(被坑多了,就记住了),但是像你这样不断试验,摸得一清二楚的,实在是值得学习。

    • 张戈 2017年8月26日 回复

      另外,这个“迷”字用得很传神。

      • dige 2017年8月26日 回复 作者

        哇靠,原来是张戈大大来了,我说怎么觉得屋子里面亮堂了许多呢。

        • 阿柯 2021年3月2日 回复

          你这个评论,作者回复评论后面有“作者”标识的,我原来也有,没有备份,把它删了,现在又想要,能把这段代码给我么?谢谢啦

          • dige 2021年3月3日 作者

            已经发到你邮箱,应该没找错代码段。第68行。

  • 紫茎泽 2017年9月16日 回复

    醍醐灌顶啊。

  • 武陵人 2017年10月18日 回复

    匹配顺序和匹配优先级都得兼顾

  • 老刘 2017年10月28日 回复

    写这样一篇出来,得好几个小时吧。

  • 山野愚人居 2017年11月2日 回复

    一直用的nginx,上次也调整location,折腾了好久!

  • 爆小妹 2017年11月2日 回复

    大神就是大神666

  • 明月清风 2017年11月4日 回复

    大佬技术好!

  • 老刘 2017年11月4日 回复

    阅读人数居然少于评论数?!!

    • dige 2017年11月5日 回复

      刚启用阅读人数统计,所以这样。

      • 老刘 2017年11月5日 回复

        原来如此。

  • 夏日博客 2017年11月5日 回复

    Nginx真是个伟大的软件之一。

  • 懿古今 2017年11月6日 回复

    看完之后还是晕乎乎的,我每次想用的时候都是依葫芦画瓢的

  • 历史趣谈 2017年11月15日 回复

    经常互换有益网站健康发展

  • 钟水洲博客 2017年11月18日 回复

    文章不错,希望博主回访,另外可以的话加一下我的博客交流群

  • 墨水 2017年11月20日 回复

    写的太高深,支持写作、分享。

  • 花记App 2017年11月20日 回复

    无意间发现你的博客,挺棒的,关注啦

  • 木先森 2017年11月21日 回复

    身高2米6,那是阿凡达,哈哈。博主这种肯钻研的精神值得点赞!

  • 明月清风 2017年11月24日 回复

    有所学习,不错

  • 钟水洲博客 2017年11月30日 回复

    技术文章,钟水洲博客要顶

  • 熊童子 2017年12月1日 回复

    看 的不是这么太懂嘿嘿

  • 墨水 2017年12月5日 回复

    虽然不懂,但是得顶!

  • 明月登楼 2017年12月20日 回复

    哎,我是一看到“正则”就晕菜了!所以很少有动力去折腾Nginx这方面的东西!

  • 钟水洲博客 2018年1月1日 回复

    钟水洲博客来访,祝贵站2018快乐,不忘初心,一路坚持

  • 品牌馆 2018年1月8日 回复

    互动率很高的网站,不错哦

  • 西枫里博客 2018年1月11日 回复

    字符串和非正则啥区别?=和正则我明白

  • 西枫里博客 2018年1月14日 回复

    当里个当当里个当,博主偷懒不看评论。。。

  • 在线看小说 2018年1月14日 回复

    嘿嘿,看不懂啊,支持!

  • 贷款口子 2018年1月15日 回复

    博主很厉害啊

  • 灯芯绒 2018年1月18日 回复

    高技术文章,一般这都交给空间商

  • 品牌馆 2018年1月19日 回复

    技术宅,很不错的分享

  • 西枫里博客 2018年2月16日 回复

    西枫里给您拜年了,祝您春节快乐,万事如意,狗年旺旺,博客访问量如芝麻开花般节节高!

  • 玉苏子 2018年2月23日 回复

    一样看不懂,博主很厉害!

  • 玉苏子 2018年2月24日 回复

    大家都说好,为啥我看不懂呢

  • 梁兴健 2018年3月1日 回复

    看了评论区这么人看不懂你在写什么,我也就放心了,因为我也看不懂,嘻嘻

  • 鸟叔 2018年3月3日 回复

    纯技术类文章,看的好累

  • 钛客志 2018年3月3日 回复

    使用vps就来你这边参考一下实例,挺好

  • 浇注料 2018年3月27日 回复

    总结得很详细,感谢分享

  • 图南山 2018年3月28日 回复

    看不懂看不懂

  • 应用志 2018年4月24日 回复

    对系统运维是一窍不通,这些字我都认识,可是放在一起却看不懂

  • 老陈网志 2018年5月5日 回复

    好文章!

  • 广州网站建设 2018年5月11日 回复

    厉害了,感谢分享

  • 老陈网志 2018年5月17日 回复

    博主好久没更新了啊!

  • 山野愚人居 2018年5月19日 回复

    这讲解的深刻啊,学习了,我一直用的nginx。

  • 小橙子 2018年6月7日 回复

    分析的很透彻,一直用着nginx 比其他的感觉要轻不少

  • Mr.路 2018年6月14日 回复

    人气很高啊 哈哈

  • 每日博客 2018年6月18日 回复

    看见正则就头疼...

  • 千眼网 2018年6月27日 回复

    干货收藏了,感谢博主分享。

  • Serious 2018年7月15日 回复

    膜拜大佬~~

  • ssr 2018年8月13日 回复

    这个比喻非常6了,哈哈

  • 于闻观纸 2018年8月15日 回复

    666,为你大call

  • 分板机 2018年9月8日 回复

    很专业,有深度的技术博客

  • 头条 2018年9月9日 回复

    文章不错非常喜欢

  • Nginx的location规则迷之匹配 – 小俊博客 2018年9月15日 回复

    […] 本文转载自笛声的Nginx的location规则迷之匹配 […]

  • 塑胶跑道 2018年10月13日 回复

    非常实用哇,马上试试。

  • wordpress建站吧 2018年12月24日 回复

    nginx的重写不会 啊

  • Joe 2019年1月2日 回复

    不明觉利,读过这篇文章,感觉从战术上还是一窍不通,但是从战略上,已经心领神会了。

  • countmeon 2019年2月15日 回复

    太过详实,没有看完。不过佩服博主的精神

  • 刘少技术博客 2019年4月8日 回复

    Nginx真的好用,但是里面涉及的技术也真的好多~~

  • 城南花已开 2019年4月10日 回复

    好东西就要留着,指不定哪天就需要用到了,感谢大佬!

  • 楚狂人 2019年5月12日 回复

    好专业的文章,收藏

  • wordpress建站吧 2019年5月19日 回复

    永远学不会记不住,都是每次哟用到了再看看。。。。

  • 心灵博客 2019年5月30日 回复

    终于遇到个和我一样的强迫症患者了,一看都是技术大牛。
    我写的NGINX规则只能说是能用,优化还有段距离。

  • 武陵红苗 2019年6月25日 回复

    大神我来了

  • 武陵红苗 2019年6月25日 回复

    两年前来过,今天又来了,缘分啊。

  • 杀马特贵族 2019年11月21日 回复

    留下印记

  • 增城职业技术学校 2020年1月15日 回复

    网站内容还是挺不错的,谢谢博主。还有博客应该是WORDPRESS做的吧,感觉美观度还可以提高,谢谢。我自已是搞前端设计的,你的代码可以做精简一点。

  • 交流充电桩检测设备 2020年12月30日 回复

    好久没来了

  • 找一找 2021年2月28日 回复

    我是菜鸟,虽然不懂,但是得顶!

  • 美樂地 2021年3月27日 回复

    真心看不懂,不过我知道自己的VPS是LNMP,N就是Nginx

  • 一介大叔 2021年6月19日 回复

    语法最终控制一切……

  • rantrism 2021年7月28日 回复

    您好~我是腾讯云+社区的运营,关注了您在分享的技术文章,觉得内容很棒,我们诚挚邀请您加入腾讯云自媒体分享计划。完整福利和申请地址请见:https://cloud.tencent.com/developer/support-plan
    作者申请此计划后将作者的文章进行搬迁同步到社区的专栏下,你只需要简单填写一下表单申请即可,我们会给作者提供包括流量、云服务器、域名等,另外还有些周边礼物。 我们诚挚的邀请您并期待您的加入~

  • wu先生 2021年9月14日 回复

    不明觉历。

  • 老狼 2021年10月9日 回复

    你这个几年前的老文章置顶,我一直以为你没更新。。。

  • 一介大叔 2021年11月25日 回复

    发现很多人一样看不懂,放心了。

  • 我要学习网 2022年5月17日 回复

    这篇文章再次证明了我真的啥也不会呀。。

  • sedbes 2023年5月8日 回复

    这篇文章真干货,以前为了方便全用~*

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Copyright © 2015-2024 笛声博客 All Rights Reserved     浙ICP备15036123号-1