Apache Webserver блокирует подключение внешнего интерфейса на обратном прокси error

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

Проблема начинается, когда приложение выходит из строя. Это заставляет Apache выдавать код ошибки.

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

Можно ли настроить Apache так, чтобы он отклонял запрос tcp на серверной части из-за внутренней ошибки?

1
задан 3 July 2019 в 18:01
3 ответа

Haproxy может отклонять TCP-соединения на основе динамических условий, включая количество серверов, доступных на бэкэнде. Ключевое слово config - это соединение tcp-request. (Ссылка на документы ниже.)

Итак, можно поставить haproxy перед Apache (я знаю, я знаю! Три слоя?!?!) Или, может быть, использовать haproxy вместо Apache.

Может выглядеть так (не проверено):

frontend http-in
  bind *:80
  mode http
  tcp-request connection reject if nbsrv(appfarm) lt 1
  default_backend appfarm

backend appfarm
  server appsrv01 127.0.0.1:8888 check

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

2
ответ дан 3 December 2019 в 23:03

Это, вероятно, не будет работать с самим apache httpd. Проблема в том, что ваше неудачное приложение заставляет apache httpd генерировать ошибку. Эта ошибка возникает только тогда, когда вы действительно запрашиваете URL-адрес из этого приложения. Apache httpd нужен URL-адрес, чтобы решить, ошибка это или нет, и чтобы получить URL-адрес от клиента, ему необходимо TCP-соединение.

Что можно сделать в качестве обходного пути: Вы можете написать довольно простой скрипт, который считывает поток ErrorLog на stdin, а затем блокирует запросы от ваших балансировщиков нагрузки (возможно, iptables), как только начинают возникать ошибки. Затем этот сценарий можно настроить в качестве приемника журнала ошибок apache httpd с помощью директивы ErrorLog.

Это отключит внутренний сервер apache httpd, но никогда не сможет повторно включить его автоматически.

0
ответ дан 3 December 2019 в 23:03

Я перенесу логику на балансировщик нагрузки, если невозможно заменить существующий балансировщик нагрузки, установлю небольшой nginx на каждом сервере Apache для прокси-соединения.

[Пользователь] - [Балансировщик нагрузки] - [ Nginx ] - [Apache]

Используя nginx в качестве балансировщика нагрузки или обратного прокси , вы получаете доступ к ответам восходящего потока (В вашем случае Apache), и вы можете создать правила, которые оценивают код ответа перед тем, как отвечать конечному клиенту:

$ upstream_status сохраняет код состояния ответа, полученного от вышестоящий сервер. Коды состояния нескольких ответов разделены запятые и двоеточия, такие как адреса в переменной $ upstream_addr. Если сервер не может быть выбран, переменная сохраняет значение 502 (Bad Gateway) код состояния.

Примеры правил Nginx

Вызов API балансировщика нагрузки для удаления узла, если он доступен:

if ($upstream_status != 200) {
    return 301 return 301 http://loadbalance/api/remove/node;
} 

Вызов локального сценария (, проверьте безопасность ), чтобы убить Apache и попросить пользователя перезагрузить страницу ( в следующий раз он будет использовать другой бэкэнд). Он использует ngx_http_lua_module .

if ($upstream_status != 200) {
   content_by_lua_block {
     os.execute("/bin/killapache.sh")
   } 
   return 301 https://$host$request_uri;
} 
-1
ответ дан 3 December 2019 в 23:03

Теги

Похожие вопросы