web-dev-qa-db-fra.com

Comment configurer correctement Apache Httpd en tant qu'équilibreur de charge où certains hôtes peuvent ne pas être disponibles

J'utilise une instance Apache Httpd en tant que proxy devant plusieurs instances Java Tomcat. Apache agit en tant qu'équilibreur de charge pour les instances de Tomcat.

La configuration d'Apache ressemble en gros à ce qui suit

<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>

Cela fonctionne essentiellement lorsque les ports AJP sont configurés dans les instances de Tomcat. Les demandes sont envoyées à l'un des hôtes et la charge est répartie sur les instances de Tomcat.

Cependant, je vois de très longs retards qui semblent être causés à l'intérieur de Httpd chaque fois qu'un des hôtes n'est pas disponible, c'est-à-dire qu'il semble qu'Apache ne se souvienne pas que l'un des hôtes n'est pas disponible et tente à plusieurs reprises d'envoyer des demandes également aux hôtes manquants en l'envoyant à l'un des hôtes disponibles et en essayant l'hôte défaillant ultérieurement.

Est-il possible de configurer mod_proxy et.al. Apache Httpd pour prendre en charge un tel scénario de basculement, c’est-à-dire avoir plusieurs hôtes et ne pas causer de retards importants lorsqu’un hôte échoue? De préférence, Apache doit vérifier périodiquement en arrière-plan quels hôtes ont disparu et non comme eux pour les demandes.

J'ai trouvé HAProxy qui semble mieux convenir à ce genre de chose, mais je préférerais rester avec Apache pour un certain nombre de raisons indépendantes.


Mettre à jour

Entre-temps, j'ai découvert qu'une partie de mon problème était due à des clients qui maintenaient la connexion ouverte indéfiniment. Il n'y avait donc plus de connexions/threads disponibles.

Je change donc la question en: Quelles options de configuration utiliseriez-vous pour minimiser l’effet de ce genre de chose? C'est à dire. autoriser de nombreuses connexions ouvertes ou les fermer rapidement dans ce cas? Sinon, cela ressemble à une attaque DOS très facile avec ma configuration actuelle?

11
centic

Les clients ne garderont pas la connexion ouverte indéfiniment. Vérifiez votre serveur Apache server-tuning.conf et recherchez le paramètre KeepAliveTimeout. Abaissez-le à quelque chose de sensé.

Vos modifications de ConnectionToutout et de réessayer sont bien ce que vous devez faire. Je voudrais réduire le temps de connexion si. 10 secondes sont encore des âges. Si le serveur principal se trouve au même endroit, pourquoi ne pas le définir en millisecondes? temps de connexion = 200 ms devrait laisser suffisamment de temps pour configurer la connexion.

6
Amblyopius

Je pense avoir au moins trouvé une solution de contournement ou une solution simple. mod_proxy semble avoir un délai de connexion très long par défaut (300 secondes). si vous ne le définissez pas différemment, il faudra beaucoup de temps avant que les nœuds hors ligne ne soient détectés comme étant dans l'état "err".

En définissant un délai de connexion court et en augmentant le nombre de tentatives, je pouvais le rendre plus efficace pour moi:

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

Cela garantira que les connexions défaillantes seront détectées assez rapidement et qu'Apache ne réessayera pas trop souvent pour atteindre les serveurs défaillants. Malheureusement, il semblerait qu'Apache utilise les requêtes réelles pour vérifier les membres de la balance et que, de temps en temps, des requêtes individuelles puissent donc être lentes lorsqu’elle tente d’atteindre un serveur précédemment placé dans un état d’erreur. Il semble qu'il n'y ait pas de rythme cardiaque ou de fonction de surveillance. Pour quelque chose comme cela, d'autres solutions d'équilibrage de charge apportent de telles fonctionnalités, notamment HAProxy

Lire sur mod_proxy et mod_proxy_balancer pour plus de détails. 

De plus, l'état du serveur via mod_status et le gestionnaire de solde via une page fournie par mod_balancer ont été d'une grande aide pour le diagnostic!

2
centic

Il semble que vous ayez oublié le ping tag (en fait, il s’appelle CPING - 100-Continue)

Ainsi:

<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/"
1
mjoao