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

Как заставить nginx try_files своевременно получать html-ресурсы

С помощью nginx 1.8.1 на Amazon Linux EC2 пример. Использование в качестве обратного прокси для поддержки https для Apache работает на другом экземпляре. Все работает нормально, кроме этой проблемы.

Я хочу обслуживать статическую страницу из nginx на случай, если я захочу взять Apache экземпляр сервера не работает. Итак, я сделал это:

    location   / {
        try_files /site-down.html $uri @backend;
    }

Поэтому перед тем, как выключить внутренний сервер, я создаю символическую ссылку в nginx корневой каталог сервера в статический файл HTML, который выглядит следующим образом:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  <title>example.com</title>
  <style type="text/css">
  body {
    background-image:url('/images/back-soon-background.jpg');
    font-family: arial,verdana,sans-serif;
    text-align: center;
  }
  #msg {
    background-image: url('/images/back-soon-oval.png');
    background-repeat: no-repeat;
    width: 600px;
    padding-top: 140px;
    padding-left: 50px;
    padding-right: 50px;
    padding-bottom: 150px;
  }
  </style>
</head>

<body>
<div id="msg">
<h1>Sorry, the site is currently unavailable.</h1>
<h2>We expect to be back within 2 hours.</h2>
</div>
</body>
</html>

Проблема в том, что когда я это делаю, страница сразу же отображается как текстовое содержимое div, без изображений, указанных <style> в <head> раздел. С помощью Chrome Инструменты разработчика Вкладка Сеть, я вижу, что запросы на URL-адреса изображений выходят и получают 200 кодов состояния. Но если я нажимаю на эти запросы, предварительный просмотр недоступен, а длина тела слишком короткая. Перезагрузка страницы помогает не сразу. Но если я оставлю его там на некоторое время, в конечном итоге появится правильный результат с изображениями. Если я укажу в браузере прямо на /site-down.html, страница сразу отображается правильно.

Обе Chrome 52.0.2743.116 m и Firefox 48.0.2 веди себя так же. Я новичок в nginx, но я не могу представить, почему первый uri в try_files должны вести себя иначе, чем переходить непосредственно к этому uri в случае, если файл существует. Что мне не хватает?

Комментарии @ Michael-Hampton дали ответ на вопрос, который я задал. Около 6 недель назад я предположил, что, если он разместит эту информацию в качестве ответа, я помечу ее как принятую. Но поскольку он этого не сделал, я создаю здесь ответ, чтобы принять его. Похоже, стыдно оставлять это без ответа.

Ответ на вопрос, который я задал, заключается в том, что указанная мной конфигурация nginx принудительно все запросы на первую попытку обслуживания статического site-down.html страница. И поскольку изображения были указаны как URL-адреса одного и того же сайта, эти запросы изображений также обрабатывались / location директива, поэтому try_files были применены и изменили их также для обслуживания site-down.html страница.

Я не знаю, почему изображения в конечном итоге вообще появились после некоторых перезагрузок и ожидания, должно быть, что-то истекло.

Самый прямой способ решить проблему, как я видел, - это изменить URL-адрес фонового изображения на data URL с самим содержимым изображения, встроенным в base64 струны. Тем самым site-down.html page не генерирует никаких дополнительных запросов на ресурсы и работает так, как я задумал изначально.

Но он также отметил, что то, что я пытаюсь сделать во время работы, дает код состояния 200, даже если сайт в основном не работает. Я объяснил, что сайт предназначен исключительно для интерактивных пользователей, а не для серверов, и предназначен для краткосрочных преднамеренных отключений, а не для ошибок, таких как сбой внутреннего сервера. Так что я не вижу в этом большой проблемы. Но правда в том, что всегда лучше давать значимый код статуса. Поэтому я считаю, что «правильным» решением для меня является наличие двух разных «доступных» файлов конфигурации nginx, один из которых просто жестко кодирует ответ 503, используя site-down.html в качестве настраиваемой страницы ошибок. Затем вместо того, чтобы создавать / удалять символическую ссылку с именем site-down.html в корне и полагаться на try_files для получения желаемого поведения, я должен просто изменить символическую ссылку в каталоге с поддержкой сайтов, чтобы выбрать правильную конфигурацию и выполнить sudo service nginx reload для плавного переключения поведения.

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

try_files пробует файлы в указанном вами порядке. Измените порядок на что-то вроде этого

try_files $uri @backend /site-down.html;

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

Использовать error_page директива для обработки ситуации, когда ваш бэкэнд не работает. Это также позволит вам вернуть правильный код ответа HTTP.

Например:

server {
    try_files $uri @backend;

    error_page 500 502 503 504 =503 /site-down.html;

    #....

В этом случае мы сначала обслуживаем статические файлы, а затем переходим на серверную часть. Если бэкэнд возвращает одну из перечисленных ошибок, то nginx будет обслуживать /site-down.html с ответом HTTP 503.

Преимущество этого метода в том, что вам не нужно вручную добавлять или удалять site-down.html файл. Вы оставляете его на месте, и nginx автоматически обслуживает его, если серверная часть фактически вниз.