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

Перезапись URL HAProxy при ошибке 404

Как заставить HAProxy перезаписывать другой сервер, если в первом отсутствует файл? Мне нужно errorloc но вместо перенаправления выполняется перезапись, поэтому клиент не знает о перенаправлении.

Мы разработали приложение с учетом NginX, которое одновременно использовало обратный прокси-сервер с балансировкой нагрузки и веб-сервер для статических файлов. Приложение основано на Опа framework, который требует закрепленных сеансов на основе файлов cookie - поддерживается как NginX, так и HAproxy. Проблема приложения - создание динамического контента. Он генерирует изображения по запросу, но после генерации они сохраняются на диске и могут быть доступны статически с детерминированным путем.

Проблема была легко решена с помощью NginX - он пытается прочитать локальный файл и использовать серверную часть с балансировкой нагрузки, только если файл отсутствует (еще не сгенерирован):

server {
  server_name wkaliszu.pl;
  location /thumb {
    root /path_on_disk/to_cached_content;
    expires 7d;
    # try to access already generated content
    try_files $uri @wkaliszu;
  }
  location / {
    # reverse proxy to the application
    [...]
  }
  location @wkaliszu {
    # reverse proxy to the application
    [...]
  }
}

Сервер был перенесен и теперь использует HAPproxy для балансировки нагрузки, который не является веб-сервером и не поддерживает эту функцию. Теперь динамическое создание программного обеспечения выполняется каждый раз, когда клиент пытается получить доступ к ресурсу, что намного медленнее и расходует ресурсы. Было бы хорошо, если бы он мог использовать следующий бэкэнд, если бы первый (простой веб-сервер кеширования статических файлов) вышел из строя с ошибкой 404, но я не могу найти способ сделать это простым способом. Перенаправление /thumb в NginX, который пытается прочитать статический файл и снова перезаписывает HAproxy с новым заголовком HTTP, мне приходит только в голову, но я бы хотел найти что-то получше.

Бэкэнды HAProxy либо работают, либо опускаются (или находятся на пути к подъему / падению).

Существуют различные способы проверить работоспособность серверной части, но я не знаю ни одного, обеспечивающего отслеживание на основе запроса. Как только запрос не выполняется, этот бэкэнд будет помечен как неработающий или будет отказывать (на пути к тому, чтобы считаться отключенным).

Это совершенно другая логика, чем ваша установка Nginx, которая маршрутизировала запросы для каждого запроса.

Я вижу здесь несколько вариантов:

  • Nginx как кеширующий прокси
  • Использовать серверы приложений для статического содержимого
  • Используйте CDN

Кеширование прокси

В HAProxy вы должны использовать ACL для маршрутизации запросов статического контента к определенному бэкэнду. Эти внутренние узлы будут запускать nginx с кеширующим прокси. Если бы у nginx был файл в кеше, он бы просто обслужил его. Если нет, он позвонит в ваш бэкэнд.

Используйте серверы приложений для статического содержимого

Если ваши серверы приложений эффективно обслуживают статический контент, возможно, вам не потребуется разделять запрос в haproxy. Просто отправьте все запросы в серверную часть вашего приложения. Встраивайте в них логику, чтобы обслуживать статический контент, если он доступен, а если нет, отправлять запрос в бэкэнд.

Вариант CDN

Если вы можете использовать выделенный домен для статического контента, вы можете использовать CDN. В CDN вы просто указываете исходный URL-адрес узлов вашего приложения. Затем вы можете управлять кешированием на уровне CDN. Это похоже на кеширование Nginx выше, за исключением того, что провайдер CDN обрабатывает его за вас.