Назад | Перейти на главную страницу

Как перенаправить на Amazon S3 в режиме обслуживания с nginx с использованием 503?

Во время обслуживания веб-сайта иногда необходимо закрыть наш веб-сайт.

Наш текущий метод заключается в 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 Service unavailable», что я бы предпочел:

> 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)...

Я не верю, что вы можете передать перенаправление с помощью 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 обычно невозможно перенаправить пользователя с любым другим кодом состояния HTTP, кроме класса 3xx.

Пользователи, которые посещают сайт, находящийся на техническом обслуживании, заслуживают получить страницу с полезной информацией.

Сначала сделайте это с перенаправлением 302, которое приведет к странице 503, которая выводит заголовок 503 (то есть через PHP или Perl). Это будет хорошо работать с Google, поскольку Google назначит все свойства целевой страницы исходной странице, когда они встретят 302, включая ответ заголовка. Я тестировал это на виртуальных хостах, и он работает по желанию. Если можете, выберите время с несколькими запросами для действий службы.

С уважением, Томас