nginx中一些容易被忽略的问题

1.nginx 中root与alias用法与区别
#参考
http://blog.csdn.net/u011510825/article/details/50531864
#需要注意:
1. 使用alias时,目录名后面一定要加"/"。
3. alias在使用正则匹配时,必须捕捉要匹配的内容并在指定的内容处使用。
4. alias只能位于location块中。(root可以不放在location中)

 在nginx location中使用root的用法时,之前一直忽略了一点:
location ^~ /t/ {
     root /www/root/html/;
}
如果一个请求的URI是/t/a.html时,web服务器将会返回服务器上的/www/root/html/t/a.html的文件,而不是/www/root/html/a.html.
2.在nginx rewrite规则中若使用到带{ }的正则,如匹配数字2次: (\d+){2} ,由于nginx是使用{ }花括号来区分区块的,如http区块,server区块。 为了避免冲突, 正则表达式里带花括号的话,应该用双引号(或者单引号)包围。
注: 常用正则
. : 匹配除换行符以外的任意字符
? : 重复0次或1次
+ : 重复1次或更多次
* : 重复0次或更多次
\d :匹配数字
^ : 匹配字符串的开始
$ : 匹配字符串的介绍
{n} : 重复n次
{n,} : 重复n次或更多次
[c] : 匹配单个字符c
[a-z] : 匹配a-z小写字母的任意一个
3.rewrite只能放在server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用,例如 http://seanlook.com/a/we/index.php?id=1&u=str 只对/a/we/index.php重写。语法rewrite regex replacement [flag];
小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。
参考:
需要特别注意一点,如上文章中已经讲到,现摘抄下来:
nginx的rewrite有个很奇特的特性 — rewrite后的url会再次进行rewrite检查,最多重试10次,10次后还没有终止的话就会返回HTTP 500
4.关于rewrite的四个flag
last : 相当于Apache的[L]标记,表示完成rewrite
break : 停止执行当前虚拟主机的后续rewrite指令集
redirect : 返回302临时重定向,地址栏会显示跳转后的地址
permanent : 返回301永久重定向,地址栏会显示跳转后的地址

因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解:

  1. last一般写在server和if中,而break一般使用在location中
  2. last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
  3. break和last都能组织继续执行后面的rewrite指令
last和break最大的不同在于
- break是终止当前location的rewrite检测,而且不再进行location匹配
– last是终止当前location的rewrite检测,但会继续重试location匹配并处理区块中的

 

5.nginx location 关于正则的匹配优先级:
可见对于正则匹配(~,~*),是按顺序匹配,一旦匹配成功就结束匹配。

 


6.关于nginx rewrite的一点总结:

最经在配置nginx虚拟主机配置文件时,遇到一个问题:

 

需要在一个域名里,增加另外一个域名的入口,也就是两个location指向同一个后端,最开始我把两个location同时指向mps.keruyun.com的后端mps,但这里犯了一个错,就是location /supplier/在请求资源时指向也会在后端上带上supplier,也就是第一点中提到root的用法类似,也就是:mps.keruyun.com/supplier/里去了,这显然请求不到正常的页面。所以这里涉及到rewrite,最后总结出三种方法的实现:

 

#对于rewrtie有四种不同的flag,分别是redirect、permanent、break和last。其中前两种是跳转型的flag,后两种是代理型。跳转型是指有客户端浏览器重新对新地址进行请求,代理型是在WEB服务器内部实现跳转的。
#第一种可以通过浏览器跳转方式来实现,这种方式使用了跳转型flag,服务器返回302,在响应头返回location:http://mps.keruyun.com/xxx。浏览器的行为表现为:直接跳转到rewrite后的url上,也即location中所示的url.
#这里需要注意几点:1.rewrite后跟域名一定要带http,不然nginx会吧域名当成location,结果会造成循环重定向! 2.一般也不推荐这种写法,有些业务中没有增加302、301这种跳转的逻辑,非200的状态码会被当作失败的请求处理。  3.跳转型的rewrite 后面不需要写其他的内容,如proxy_pass这些语句,因为写了也不会生效。
   location /supplier/ {
        rewrite ^/supplier/(.*)$  http://mps.keruyun.com/$1 redirect;
    }  
#第二种为常见的写法,这里需要特别注意一定要带上break flag,否则rewrite重写后的地址,会重新在server中跑一次,这次会匹配到/里去,不会向下执行proxy_pass语句。
#这种写法服务器返回200,浏览器对rewrite无感知,因为代理型是在WEB服务器内部实现跳转的,浏览器请求的url保持不变!
    location /supplier/ {
        rewrite ^/supplier/(.*)$  /$1 break;
        proxy_redirect         off;
        proxy_connect_timeout 10; 
        proxy_read_timeout 30; 
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://mps;
    }   
#第三种写法为在proxy_pass upstream后加/,这样nginx在发给后端的请求中不会把location中的字段传递给后端,这种写法也需要注意一点:那就是匹配不能是正则匹配,正则匹配时这种写法会报错。
    location /supplier/ {
        proxy_redirect         off;
        proxy_connect_timeout 10; 
        proxy_read_timeout 30; 
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://mps/;
    }   

发表评论

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