Во время обслуживания веб-сайта иногда необходимо закрыть наш веб-сайт.
Наш текущий метод заключается в 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, включая ответ заголовка. Я тестировал это на виртуальных хостах, и он работает по желанию. Если можете, выберите время с несколькими запросами для действий службы.
С уважением, Томас