首页 > 解决方案 > 基于 Nginx 位置的尝试文件?

问题描述

我在这里阅读此页面https://help.sorryapp.com/en/articles/2783542-install-maintenance-pages-on-nginx有一个很好的想法,即存在文件意味着 nginx 将路由到维护 html 页面.

但是随后阅读 nginx 文档,似乎位置块中的 if 语句并不理想,而是使用 try 文件。将上面的内容重写为 nginx 想要的方式的正确方法是什么?https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/

我假设是这样的:但是重写呢?

try_files /my/file/path/maint.on
error_page 503 @maintenance_page;
location @maintenance_page {
    rewrite ^(.*)$ /maintenance_page.html break;

?

更新 1

这是我当前的配置片段,由于某种原因,即使 maint.on 文件不存在,它也会导致 404。

      location / {
         if (-f /opt/staytus/staytus/maint.on) {
            return 503;
        }
        port_in_redirect off;
                proxy_pass http://example.com:8787/;
        }

 error_page 503 @Performing-Maintenance;

    location @Performing-Maintenance {
        rewrite ^(.*)$ Performing-Maintenance.html break;
    }
}

对这个问题有任何想法吗?

标签: nginxcentos

解决方案


正如同一篇文章所述,

如果在位置上下文中,唯一可以在内部完成的 100% 安全的事情是:

  • return ...;
  • rewrite ... last;

所以你找到的例子可以被认为是完全安全的。(我会说使用块ngx_http_rewrite_module内的任何指令if将这个列表扩展到breakreturn和是安全rewriteset)。你不能用指令做你想做的事情,因为它需要在最后一个uri(或命名位置的名称或 HTTP 错误代码)参数之前try_files至少有一个文件参数,如果没有来自列表实际上是存在的。好吧,我可以想象像

location / {
    try_files /maintenance.html @default;
}

location @default {
    ...
}

但你不能让它服务于某个位置,比如

location = /maintenance.html {
    ...
}

,它只会返回maintenance.html文件的内容。如果maintenance.html页面将引用一些额外的资产(如 CSS、JS 等),则所有用户浏览器对该资产的请求都将指向maintenance.html内容(因为该文件存在并通过了try_files检查)。仅供参考,这个指令

location / {
    try_files $uri $uri/index.php =404;
}
...
location ~ \.php$ {
    ...
}

不会$uri/index.php通过 PHP 位置处理程序提供文件(它只返回其原始内容),而这

location / {
    index index.php;
    try_files $uri $uri/ =404;
}

将。

stat但是,由于对每个传入请求进行了额外的内核调用,您提供的示例会对性能产生一些影响(尤其是在高负载服务器上) 。我推荐这种使用 nginx 启用维护模式的方法。


推荐阅读