Как правильно настроить Apache Httpd как Load Balancer, где некоторые хосты могут быть недоступны

Я использую экземпляр Apache Httpd в качестве прокси-сервера перед несколькими экземплярами Java Tomcat. Apache действует как балансировщик нагрузки для экземпляров Tomcat.

Конфигурация apache в основном выглядит следующим образом

<Proxy balancer://mycluster>
    BalancerMember ajp://host1:8280 route=jvmRoute-8280
    BalancerMember ajp://host2:8280 route=jvmRoute-8280
    BalancerMember ajp://host3:8280 route=jvmRoute-8280
</Proxy>
<VirtualHost *:80>
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
</VirtualHost>

Это в основном работает, когда порты AJP настроены в экземплярах Tomcat. Запросы отправляются на один из хостов, а загрузка распределяется по экземплярам Tomcat.

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

Есть ли способ настроить mod_proxy et.al. от Apache Httpd для поддержки такого сценария перехода на другой ресурс, т.е. с несколькими узлами и не вызывать больших задержек при сбое одного хоста? Предпочтительно Apache должен периодически проверять фон, в котором хосты исчезли, а не как их для любых запросов.

Я нашел HAProxy, который, похоже, больше подходит для такого рода вещей, но я предпочел бы придерживаться Apache по ряду несвязанных причин.


Update

Тем временем я узнал, что часть моей проблемы была вызвана клиентами, которые постоянно закрывали соединение и, следовательно, больше не было подключений/потоков.

Таким образом, я меняю вопрос на: Какие параметры конфигурации вы использовали бы для минимизации эффекта чего-то подобного? То есть разрешить много открытых соединений или быстро закрыть их в этом случае? В противном случае это звучит как очень простая DOS-атака с моей текущей конфигурацией?

Ответ 1

Клиенты не будут поддерживать связь бесконечно. Проверьте свой Apache server-tuning.conf и найдите параметр KeepAliveTimeout. Опустите его к чему-то разумному.

Ваши изменения в времени подключения и повторных попытках действительно то, что вам нужно сделать. Однако я бы снизил время соединения. 10 секунд все еще возрасты. Если задний конец находится в том же месте, почему бы не установить его в милисекундах? connectiontimeout = 200ms должно уделить много времени, чтобы настроить соединение.

Ответ 2

Я думаю, что нашел хоть какое-то обходное решение или простое решение. По умолчанию mod_proxy имеет очень длительное время соединения (300 секунд). если вы не установите его по-другому, это займет много времени, пока автономные узлы не будут обнаружены как находящиеся в состоянии "err".

Установив короткое время ожидания соединения и увеличив повторную попытку, я мог бы улучшить работу для меня:

BalancerMember ajp://host1:8280 route=jvmRoute-8280 connectiontimeout=10 retry=600

Это гарантирует, что сбои в подключении обнаруживаются достаточно быстро, и Apache не слишком часто повторяет попытку для выхода из строя серверов. К сожалению, похоже, Apache использует фактические запросы для проверки членов баланса, и поэтому время от времени одиночные запросы могут быть медленными, когда он пытается достичь сервера, ранее введенного в состояние err-state. Кажется, нет функции биения сердца или сторожевого пса. Для чего-то вроде этого другие решения балансировки нагрузки приносят такие функции, особенно HAProxy

Читайте на mod_proxy и mod_proxy_balancer для более подробной информации.

Дополнительно статус сервера через mod_status и менеджер баланса через a страница, предоставленная mod_balancer, помогла диагностировать это!

Ответ 3

Кажется, вы забыли тег ping (на самом деле он называется CPING - 100-Continue)

Так же:

<Proxy "balancer://www">
    BalancerMember "http://192.168.0.100:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.101:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.102:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.103:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.104:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.105:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.106:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    SetEnv proxy-nokeepalive 1
</Proxy>
ProxyPass "/www/" "balancer://www/"
ProxyPassReverse "/www/" "balancer://www/"