nginx中的try_files 造成死循环的坑

贵贵的博客 ( http://blog.linuxphp.org/ ) :

try_files 按顺序检查文件是否存在,返回第一个找到的文件,至少需要两个参数,但最后一个是内部重定向也就是说和rewrite效果一致,前面的值是相对$document_root的文件路径。也就是说参数的意义不同,甚至可以用一个状态码 (404)作为最后一个参数。如果不注意会有死循环造成500错误。

示例1:

    location ~.*\.(gif|jpg|jpeg|png)$ {
        root /web/wwwroot;
        try_files /static/$uri $uri;
    }

原意图是访问http://example.com/test.jpg 时先去检查/web/wwwroot/static/test.jpg是否存在,不存在就取/web/wwwroot/test.jpg 

但由于最后一个参数是一个内部重定向,所以并不会检查/web/wwwroot/test.jpg是否存在,只要第一个路径不存在就会重新向然后再进入这个location造成死循环。结果出现500 Internal Server Error

实例2:

    location ~.*\.(gif|jpg|jpeg|png)$ {
        root /web/wwwroot;
        try_files /static/$uri $uri 404;
    }

这样才会先检查/web/wwwroot/static/test.jpg是否存在,不存在就取/web/wwwroot/test.jpg 再不存在则返回404 not found

 

最后:

可能你会觉得500和404好像都是错误码,差别不大,其实500不仅多次重定向浪费性能,还会影响到nginx的upstream造成错误的判断当前机器有故障而将新请求路由到其它机器甚至备用机,404则不会。

文章来源:

Author:linuxphp@qq.com(keminar)
link:http://blog.linuxphp.org/archives/1649/