Nginx⼏乎是当下绝⼤多数公司在⽤的web应⽤服务,熟悉Nginx的配置,对于我们⽇常的运维⼯作是⾄关重要的,下⾯就Nginx的location配置进⾏梳理:1)location匹配的是nginx的哪个变量?
$request_uri
2)location的匹配种类有哪些?
格式:location [ 空格 | = | ~ | ~* | !~ | !~* | @ ] /uri/ {}解释:
= 表⽰精确匹配,如果找到,⽴即停⽌搜索并⽴即处理此请求。~ 表⽰执⾏⼀个正则匹配,区分⼤⼩写匹配~* 表⽰执⾏⼀个正则匹配,不区分⼤⼩写匹配!~ 区分⼤⼩写不匹配!~* 不区分⼤⼩写不匹配
^~ 即表⽰只匹配普通字符(空格)。使⽤前缀匹配,^表⽰“⾮”,即不查询正则表达式。如果匹配成功,则不再匹配其他location。@ 指定⼀个命名的location,⼀般只⽤于内部重定向请求。例如 error_page, try_files/ 表⽰通⽤匹配,任何请求都会匹配到
------------------------------------------------------------------------对应⽰例说明:1)=server {
server_name wangshibo.com; location = /abcd { […] }}
匹配情况:
http://wangshibo.com/abcd # 正好完全匹配
http://wangshibo.com/ABCD # 如果运⾏ Nginx server 的系统本⾝对⼤⼩写不敏感,⽐如 Windows ,那么也匹配
http://wangshibo.com/abcd?param1?m2 # 忽略查询串参数(query string arguments),这⾥就是 /abcd 后⾯的 ?param1?m2 http://wangshibo.com/abcd/ # 不匹配,因为末尾存在反斜杠(trailing slash),Nginx 不认为这种情况是完全匹配 http://wangshibo.com/abcde # 不匹配,因为不是完全匹配
2)(None)
可以不写 location modifier ,Nginx 仍然能去匹配 pattern 。这种情况下,匹配那些以指定的 patern 开头的 URI,注意这⾥的 URI 只能是普通字符串,不能使⽤正则表达式。server {
server_name website.com; location /abcd { […] }}
匹配情况:
http://wangshibo.com/abcd # 正好完全匹配
http://wangshibo.com/ABCD # 如果运⾏ Nginx server 的系统本⾝对⼤⼩写不敏感,⽐如 Windows ,那么也匹配
http://wangshibo.com/abcd?param1?m2 # 忽略查询串参数(query string arguments),这⾥就是 /abcd 后⾯的 ?param1?m2 http://wangshibo.com/abcd/ # 末尾存在反斜杠(trailing slash)也属于匹配范围内 http://wangshibo.com/abcde # 仍然匹配,因为 URI 是以 pattern 开头的
3)~
这个 location modifier 对⼤⼩写敏感,且 pattern 须是正则表达式server {
server_name wangshibo.com; location ~ ^/abcd$ { […] }}
匹配情况:
http://wangshibo.com/abcd # 完全匹配
http://wangshibo.com/ABCD # 不匹配,~ 对⼤⼩写是敏感的
http://wangshibo.com/abcd?param1?m2 # 忽略查询串参数(query string arguments),这⾥就是 /abcd 后⾯的 ?param1?m2 http://wangshibo.com/abcd/ # 不匹配,因为末尾存在反斜杠(trailing slash),并不匹配正则表达式 ^/abcd$ http://wangshibo.com/abcde # 不匹配正则表达式 ^/abcd$
注意:对于⼀些对⼤⼩写不敏感的系统,⽐如 Windows ,~ 和 ~* 都是不起作⽤的,这主要是操作系统的原因。
4)~*
与 ~ 类似,但这个 location modifier 不区分⼤⼩写,pattern 须是正则表达式server {
server_name website.com; location ~* ^/abcd$ { […] }}
匹配情况:
http://wangshibo.com/abcd # 完全匹配
http://wangshibo.com/ABCD # 匹配,这就是它不区分⼤⼩写的特性
http://wangshibo.com/abcd?param1?m2 # 忽略查询串参数(query string arguments),这⾥就是 /abcd 后⾯的 ?param1?m2 http://wangshibo.com/abcd/ # 不匹配,因为末尾存在反斜杠(trailing slash),并不匹配正则表达式 ^/abcd$ http://wangshibo.com/abcde # 不匹配正则表达式 ^/abcd$
5)^~
匹配情况类似 2. (None) 的情况,以指定匹配模式开头的 URI 被匹配,不同的是,⼀旦匹配成功,那么 Nginx 就停⽌去寻找其他的 Location 块进⾏匹配了(与 Location 匹配顺序有关)6. @
⽤于定义⼀个 Location块,且该块不能被外部Client 所访问,只能被Nginx内部配置指令所访问,⽐如try_files 或 error_page location @resize {
rewrite ^/(.*)/cache/(.*)?(.*)$ /resize.php?dir=$1&path=$2$3;
rewrite ^/(.*)/orgi/cert/(.*)?(.*)$ /pass/resize?dir=$1&type=cert&path=$2$3&is_orgi=true; rewrite ^/(.*)/orgi/card/(.*)?(.*)$ /pass/resize?dir=$1&type=card&path=$2$3&is_orgi=true; rewrite ^/(.*)/orgi/(.*)/(.*)?(.*)$ /pass/resize?dir=$1&type=$2&path=$3$4&is_orgi=true; include fastcgi_params; }
如下⽰例:
#通⽤匹配location / {
root /var/www/web/; autoindex on;
autoindex_exact_size off; autoindex_localtime on;
access_log /var/www/log/nginx/access.log; error_log /var/www/log/nginx/error.log;}
#正则匹配
#proxy the php scripts to php-fpmlocation ~ \\.php(.*)$ { root /var/www/web/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; include fastcgi_params; fastcgi_read_timeout 300; }
#精确匹配
location = /hello.php { root /var/www/web/;
rewrite ^(.*)$ http://www.wangshibo.com redirect;}
产⽣的效果如下:
访问根⽬录/,匹配到location /
访问除hello.php之外的其它php程序,匹配到location ~ \\.php$,并且⽤php5-fpm去运⾏访问hello.php,匹配到location = /hello.php,访问被重定向到http://www.wangshibo.com
3)location搜索优先级顺序如何?
精确匹配 > 字符串匹配( 长 > 短 [ 注: ^~ 匹配则停⽌匹配 ]) > 正则匹配( 上 > 下 )
==========================================================================================================================在nginx的location和配置中location的顺序没有太⼤关系。正location表达式的类型有关。相同类型的表达式,字符串长的会优先匹配。
优先级排列(下⾯是在location匹配的内容是⼀样长度的path内容的情况下,⽐如匹配的path都是images的情况下):1)等号类型(=)的精确匹配优先级最⾼,精确匹配只能命中⼀个。⼀旦匹配成功,则不再查找其他匹配项。2)^~类型表达式,即字符串匹配,使⽤匹配最长的最为匹配结果。⼀旦匹配成功,则不再查找其他匹配项。
3)正则表达式类型(~ ~*)的优先级次之。如果有多个location的正则能匹配的话,则使⽤正则表达式最长的那个。4)常规字符串匹配类型。按前缀匹配。
特别注意:
字符串匹配优先搜索,但是只是记录下最长的匹配 (如果 ^~ 是最长的匹配,则会直接命中,停⽌搜索正则),然后继续搜索正则匹配,如果有正则匹配,则命中正则匹配,如果没有正则匹配,则命中最长的字符串匹配.--------------------------------------------------------------------------------------结论:
去分和不区分⼤⼩写的正则匹配优先级相同,以先后顺序来决定匹配哪⼀个.=的优先级⽐~⾼=的优先级⽐ ^~⾼^~的优先级⽐~⾼
^~优先匹配的是从根开始的匹配不加的优先级⽐~低
~与*~正则匹配的优先级按先后次序来决定的
--------------------------------------------------------------------------------------即nginx匹配的优先级顺序为:
[不加] < [~/~*] < [^~] < [=]
--------------------------------------------------------------------------------------下⾯通过⽰例进⾏验证:
1)先来测试下区分⼤⼩写和不区分⼤⼩写的优先级.如下:
location ~ /5b.txt { return 501; }
location ~* /5b.txt { return 504; }
测试结果为:
http://192.168.1.80/5b.txt ------------501http://192.168.1.80/5B.txt ------------504
将顺序反下,将~*放前⾯ location ~* /5b.txt { return 501; }
location ~ /5b.txt { return 504; }
测试结果为:
http://192.168.1.80/5b.txt ------------501http://192.168.1.80/5B.txt ------------501
结论: 去分和不区分⼤⼩写的正则匹配优先级相同,以先后顺序来决定匹配哪⼀个.
2)再来⽐较=与~的优先级
location = /5b.txt { return 502; }
location ~ /5b.txt { return 504; }
测试结果为:
http://192.168.1.80/5b.txt -------------502
结论:=的优先级⽐~⾼
3)再来⽐较下 ^~ 与 ~的优先级
location ~ /5b.txt { return 502; }
location ^~ /5b.txt { return 504; }
测试结果为:
http://192.168.1.80/5b.txt --------------504
结论:^~的优先级⽐~⾼
4)再测试 ^~ 与 = 的优先级
location ^~ /5b.txt { return 502; }
location = /5b.txt { return 504; }
测试结果:
http://192.168.1.80/5b.txt --------------504
结论:=的优先级⽐ ^~⾼
5)再来测试^~同级之间的优先级
location ^~ 5b.txt {
return 502; }
location ^~ /5b.txt/ { return 504; }
测试结果:
http://192.168.1.80/5b.txt --------------504
结论 :^~优先匹配的是从根开始的匹配
6)再来看空格(即什么都不加)与~的优先级⽐较
location /5b.txt { return 502; }
location ~ /5b.txt { return 504; }
测试结果为:
http://192.168.1.80/5b.txt --------------504
结论:空格的优先级⽐~低
优先级排序为:空格(即不加)
~与*~正则匹配的优先级按先后次序来决定的^~同级之间的匹配是按照根⽬录顺序来的
------------------------------------------------------------------------------------------再来看看下⾯的例⼦ (这⾥为了⽅⾯测试内容输出,使⽤了echo-nginx-module):
1)精确匹配,即“=”
location = /images/test.png { echo 'config1';}
location /images/test.png { echo 'config2';}
location \\/images\\/test\\.png$ { echo 'config3';}
如果此时请求 http://127.0.0.1/images/test.png 输出的内容是config1, ⽏容置疑,精确匹配优先级最⾼!
2)精确匹配的特殊情况location = / {
index index.html;}
location / {
echo 'config2';}
此时输⼊http://127.0.0.1 输出的内容是config2, 怎么精确匹配的优先级不灵了呢?
是这样的,精确匹配还是起作⽤了,请求⽬录(⾮具体⽂件),nginx会将请求内部定向到index⽂件,既此时真正的请求是http://127.0.0.1/index.html, 这是config2则被命中!所以精确匹配不要⽤来匹配/
3)字符串搜索与正则搜索location /images/test.png { echo 'config1';}
location ^~ /images/ { echo 'config2';}
location ~ \\/images\\/test\\.png$ { echo 'config3';}
location ~ \\/images\\/ { echo 'config4';}
如果此时请求http://127.0.0.1/images/test.png 输出的内容是config3,正则命中。
(虽然config1为最长匹配的字符串,此时只做记录,后⾯还要搜索正则匹配,则config3正则匹配命中),
仔细观察可以发现config4也被匹配成功了,但是正则的匹配顺序是按照location的定义顺序匹配的,所以config3命中(注意⽰例中带了\"\\\"的正则的转义符).
4)字符串匹配优先级的提升( ^~ )location /images/ { echo 'config1';}
location ^~ /images/test.png { echo 'config2';}
location ~ /images/test\\.png$ { echo 'config3';}
location ~ \\/images\\/ { echo 'config4';}
如果此时请求 http://127.0.0.1/images/test.png 输出的内容是config2, ⾸部匹配命中。
(因为字符串匹配是优先搜索的,此时发现config2 为最长的字符串匹配且为^~匹配⽅式,所以停⽌搜索正则,直接命中!)
所以这⾥的 ^~ 符号⽐较特殊,就是为了提⾼字符串匹配的优先级,优先于正则匹配.------------------------------------------------------------------/ 通⽤匹配,任何请求都会匹配到。多个location配置的情况下,需要遵循:⾸先匹配=其次匹配^~
再其次按照配置⽂件的顺序进⾏正则匹配、最后是交给/进⾏通⽤匹配
注意:当有匹配成功时,⽴刻停⽌匹配,按照当前匹配规则处理请求
看看下⾯匹配规则:#规则A
location = / {}
#规则B
location = /login {
}
#规则C
location ^~ /static/ {}
#规则D
location ~ \\.(gif|jpg|png|js|css)$ {}
#规则E
location ~* \\.png$ {}
#规则F
location !~ \\.xhtml$ {}
#规则G
location !~* \\.xhtml$ {}
#规则Hlocation / {}
那么产⽣的效果如下:
1)访问根⽬录/, ⽐如http://localhost/ 将匹配规则A
2)访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H3)访问 http://localhost/static/a.html 将匹配规则C
4)访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作⽤,⽽ http://localhost/static/c.png 则优先匹配到规则C5)访问 http://localhost/a.PNG 则匹配规则E,⽽不会匹配规则D,因为规则E不区分⼤⼩写。
6)访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分⼤⼩写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应⽤中哪⾥会⽤到。7)访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应⽤服务器,⽐如FastCGI(php),tomcat(jsp),nginx作为⽅向代理服务器存在。
注意:在实际使⽤中,⾄少清楚下⾯匹配规则
1)直接匹配⽹站根,通过域名访问⽹站⾸页⽐较频繁,使⽤这个会加速处理,官⽹如是说。2)这⾥是直接转发给后端应⽤服务器了,也可以是⼀个静态⾸页
第⼀个必选规则:location = / {
proxy_pass http://tomcat:8080/index}
第⼆个必选规则是处理静态⽂件请求,这是nginx作为http服务器的强项有两种配置模式,⽬录匹配或后缀匹配,任选其⼀或搭配使⽤location ^~ /static/ { root /webroot/static/;}
location ~* \\.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/;}
第三个规则就是通⽤规则,⽤来转发动态请求到后端应⽤服务器⾮静态⽂件请求就默认是动态请求,⾃⼰根据实际把握毕竟⽬前的⼀些框架的流⾏,带.php,.jsp后缀的情况很少了location / {
proxy_pass http://tomcat:8080/}
看看下⾯⼏个设置
# 重写跳转
rewrite \"^/conference/([^/]+)$\" /con_detail.php?con_title=$1 last;rewrite \"^/conference/([^/]+)/$\" /con_detail.php?con_title=$1 last;
#屏蔽爬⾍
if ($http_user_agent ~* \"qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNB {
return 403; }
#favicon.ico不⽤打⽇志 location = /favicon.ico { log_not_found off; access_log off; }
#不允许访问隐藏⽂件location ~ /\\. { deny all;
access_log off; log_not_found off;}
#访问图⽚,flash⽂件等不⽤打⽇志
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 7d; #⽂件返回的过期时间是7天 access_log off;}
#访问js和css⽂件不⽤打⽇志location ~ .*\\.(js|css)?$ {
expires 1d; #⽂件返回的过期时间是1天 access_log off;}
#设置php-cgi
location ~ [^/]\\.php(/|$) {
fastcgi_split_path_info ^(.+?\\.php)(/.*)$; #拦截不存在的php页⾯请求
if (!-f $document_root$fastcgi_script_name) { return 404; }}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- sceh.cn 版权所有 湘ICP备2023017654号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务