Как правильно настроить 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/"