Как сделать так, чтобы HAProxy переписывал на другой бэкэнд, когда в первом отсутствует файл? Мне нужно errorloc
только переписать вместо перенаправления, чтобы клиент не знал о перенаправлении.
Мы разработали приложение с учетом NginX, которое было одновременно балансировкой нагрузки обратного прокси-сервера и веб-сервера для статических файлов. Приложение основано на платформе Opa, для которой требуются липкие сеансы на основе файлов 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 для балансировки нагрузки, который не является веб-сервером и не поддерживает эту функцию. Теперь динамическая генерация программного обеспечения выполняется каждый раз, когда клиент пытается получить доступ к ресурсу, что намного медленнее и тратит ресурсы впустую. Было бы хорошо, если бы он мог использовать следующий back-end, если первый (простой кеширующий веб-сервер для статических файлов) завершился ошибкой 404, но я не могу найти способ сделать это простым способом. Перенаправление /thumb
на NginX, который пытается прочитать статический файл и снова перезаписывает на HAproxy с новым заголовком HTTP, только приходит мне в голову, но я хотел бы найти что-то лучшее.
Ответы:
Бэкэнды HAProxy находятся либо вверх, либо вниз (или на пути вверх / вниз).
Существуют различные способы проверки работоспособности бэкэнда, но я не знаю ни одного, обеспечивающего отслеживание по запросу. Как только запрос завершается неудачей, этот бэкэнд будет помечен как выключенный или будет неуспешным (на пути к тому, чтобы считаться неработающим).
Это очень отличная логика от вашей установки Nginx, которая направляла запросы на основе запросов.
Я вижу пару вариантов здесь:
Кэширующий прокси
В HAProxy вы будете использовать ACL для маршрутизации запросов статического содержимого к определенному бэкэнду. Эти внутренние узлы будут запускать nginx с кеширующим прокси. Если бы у nginx был кешированный файл, он бы его обслуживал. Если нет, это вызвало бы ваш бэкэнд.
Используйте серверы приложений для статического контента
Если ваши серверы приложений эффективны в обслуживании статического контента, вам может не потребоваться разделять запрос по haproxy. Просто отправьте все запросы к вашему приложению. Создайте в них логику для обслуживания статического содержимого, если оно доступно, а если нет, отправьте запрос на сервер
Опция CDN
Если вы можете использовать выделенный домен для статического контента, вы можете использовать CDN. В CDN вы просто указываете исходный URL-адрес ваших узлов приложения. Затем вы можете контролировать кэширование на уровне CDN. Это похоже на кэширование Nginx, описанное выше, за исключением того, что поставщик CDN обрабатывает его для вас.
источник