当 nginx 处于维护模式时如何使用 503 转发到 Amazon S3?

当 nginx 处于维护模式时如何使用 503 转发到 Amazon S3?

在网站维护期间,有时需要关闭我们的网站。

我们目前的方法是使用touch一个文件来触发网络服务器(nginx) 将流量重定向到托管在 Amazon S3 中的维护页面。将维护页面托管在外部服务器上非常重要,因为在维护期间无法保证任何本地文件的可用性。

这是我们用于“维护模式”的 nginx 配置:

server {
    ...

    # Redirect processing of 503 error pages into a named location:
    error_page 503 @maintenance;

    # "Maintenance Mode" is off by default - Use a nginx variable to track state.
    set $maintenance off;

    # Swith on "Maintenace Mode" if a certain file exists.
    if (-f /var/www/mysite/shared/maintenanceON) {
        set $maintenance on;
    }
    # Don't use "Maintenance Mode" for our own offices.
    if ($remote_addr ~ (69.69.96.69|69.69.69.79)) {
        set $maintenance off;
    }
    # Don't use "Maintenance Mode" for certain urls, e.g. the load-balancer ping page.
    if ($uri ~ ^/(site\/ping|robots\.txt)$) {
        set $maintenance off;
    }

    if ($maintenance = on) {
        return 503; # 503 - Service unavailable
    }

    location @maintenance {
        # Redirect the request to our maintenance page in Amazon S3.
        rewrite ^(.*)$ http://mysite.s3-website-us-east-1.amazonaws.com/ break;
    }

    ...

效果很好。但是有一个不良副作用,我想知道是否可以避免?

rewrite是由 Nginx 使用 302 http 状态代码将请求转发到 Amazon S3 站点来完成的。因此,在维护模式下,我们不会返回 503,而是返回 302。这不是好的礼仪,如果 Google 机器人在计划的网站停机期间抓取我们,可能会很糟糕。Google 建议使用 503 (来源)。

是否有一个 nginx 指令可以用来获得相同的效果,但不需要 302 重定向?


这表明维护模式返回“302 暂时移动”,而不是我更喜欢的“503 服务不可用”:

> wget http://staging.example.com
--2013-11-13 10:00:47--  http://staging.example.com/
Resolving staging.example.com (staging.example.com)... 69.69.69.80
Connecting to staging.example.com (staging.example.com)|69.69.69.80|:80... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: http://example.s3-website-us-east-1.amazonaws.com/ [following]
--2013-11-13 10:00:53--  http://example.s3-website-us-east-1.amazonaws.com/
Resolving example.s3-website-us-east-1.amazonaws.com (example.s3-website-us-east-1.amazonaws.com)...

答案1

我不相信您可以使用 503 传递重定向,因为它不是用于重定向的。

您要么需要将该特定文件托管在安全的位置,以使其不受正在实施的维护系统的影响,要么使用 proxy_pass 以便 nginx 从 amazon 获取页面,然后将其传递给客户端。

类似这样的方法可能会奏效。有一段时间没碰过 nginx 了,但这可能会让您了解我的建议:

    error_page 503 @maintenance;
    location @maintenance {
            rewrite ^(.*)$ /maintenance.html break;
            proxy_pass http://mysite.s3-website-us-east-1.amazonaws.com;
    }

编辑:在引用 Google 对 503 的建议的页面上,有人评论了一个关于如何使用 503 重定向的绝妙想法。他提到了 Apache 的想法,但概念与 nginx 相同:

你好!

这可能有帮助。在 Apache 服务器上,通常无法使用 3xx 类以外的任何其他 HTTP 状态代码重定向用户。

访问正在维护的网站的用户应该获得有用的信息页面。

首先使用 302 重定向执行此操作,该重定向指向输出 503 标头的 503 页面(即通过 PHP 或 Perl)。这对 Google 来说很有效,因为 Google 会在遇到 302 时将所有目标页面属性分配给源页面 - 包括标头响应。我已经在虚拟主机上测试过它,它按预期工作。如果可以,请选择一个请求较少的时间进行服务操作。

问候,托马斯

相关内容