web-dev-qa-db-fra.com

Détection d'échec du serveur d'arrière-plan d'équilibrage de charge du proxy Apache

Voici mon scénario (conçu par mon prédécesseur):

Deux serveurs Apache servant de service de proxy inverse pour un certain nombre de serveurs Web backend mixtes (Apache, IIS, Tomcat, etc.). Il existe certains sites pour lesquels nous avons plusieurs serveurs Web principaux, et dans ces cas, nous faisons quelque chose comme:

<Proxy balancer://www.example.com>
    BalancerMember http://192.168.1.40:80
    BalancerMember http://192.168.1.41:80
</Proxy>
<VirtualHost *:80>
    ServerName www.example.com:80
    CustomLog /var/log/Apache2/www.example.com.log combined
    <Location />
        Order allow,deny
        Allow from all
        ProxyPass balancer://www.example.com/
        ProxyPassReverse balancer://www.example.com/
    </Location>
</VirtualHost>

Donc, dans cet exemple, j'ai un site (www.example.com) dans les configurations des serveurs proxy, et ce site est mandaté à l'un ou l'autre des deux serveurs principaux, 192.168.1.40 et .41.

J'évalue ceci pour m'assurer que nous sommes tolérants aux pannes sur tous nos services Web (j'ai déjà mis les deux serveurs proxy inversés dans un cluster IP partagé pour cette raison), et je veux m'assurer que le chargement- Les serveurs backend équilibrés sont également tolérants aux pannes. Mais j'ai du mal à déterminer si la détection de défaillance du backend (et la logique pour éviter le serveur backend défaillant) est intégrée au module mod_proxy_balancer ...

Donc, si 192.168.202.40 tombe en panne, Apache le détectera-t-il (je comprendrai-t-il si une demande a échoué en premier) et routera automatiquement toutes les demandes vers l'autre backend, 192.168.202.41? Ou continuera-t-il à équilibrer les demandes entre le backend défaillant et le backend opérationnel?

J'ai trouvé des indices dans la documentation Apache pour mod_proxy et mod_proxy_balancer qui semblent indiquer que l'échec peut être détecté ("maxattempts = Nombre maximum de tentatives de basculement avant d'abandonner. "," failonstatus = Une liste unique ou séparée par des virgules de codes d'état HTTP. Si elle est définie, cela forcera le travailleur à l'état d'erreur lorsque le backend renvoie un code d'état dans la liste. "), mais après quelques jours de recherche, je 'ai rien trouvé de concluant pour dire avec certitude qu'il détectera (ou du moins "devrait") détecter l'échec et la récupération du backend.

Je dirai que la plupart des résultats de recherche font référence au protocole AJP pour transmettre le trafic aux serveurs principaux, et cela prend apparemment en charge la détection des échecs - mais mes systèmes principaux sont un mélange d'Apache, IIS, Tomcat et d'autres, et je suis assez sûr que beaucoup d'entre eux ne prennent pas en charge AJP. Ils sont également un mélange de boîtes Windows 2k3/2k8 et Linux (principalement Ubuntu Lucid) exécutant diverses applications différentes avec des exigences différentes, donc les modules supplémentaires comme Backhand et LVS ne sont pas une option pour moi.

J'ai également essayé de tester empiriquement cette fonctionnalité, en créant un nouveau site de test comme celui-ci:

<Proxy balancer://test.example.com>
    BalancerMember http://192.168.1.40:80
    BalancerMember http://192.168.1.200:80
</Proxy>
<VirtualHost *:80>
    ServerName test.example.com:80
    CustomLog /var/log/Apache2/test.example.com.log combined
    LogLevel debug
    <Location />
        Order allow,deny
        Allow from all
        ProxyPass balancer://test.example.com/
        ProxyPassReverse balancer://test.example.com/
    </Location>
</VirtualHost>

Où 192.168.1.200 est une adresse bidon qui n'exécute aucun serveur Web, pour simuler une défaillance du backend. Le site de test a été servi sans problème pour un tas de différentes machines clientes, mais même avec le niveau de journalisation défini pour déboguer, je n'ai rien vu dans le journal pour indiquer qu'il a détecté que l'un des serveurs principaux était en panne ... Et Je voudrais être sûr à 100% que je peux supprimer nos backends à charge équilibrée pour la maintenance (un à la fois, bien sûr) sans affecter les sites de production.

14
Jon Heese

http://httpd.Apache.org/docs/2.4/mod/mod_proxy.html Section "Paramètres BalancerMember", propriété = réessayez:

Si le travailleur du pool de connexions au serveur principal est dans l'état d'erreur, Apache httpd ne transmettra aucune demande à ce serveur jusqu'à l'expiration du délai. Cela permet à [one] d'arrêter le serveur principal pour maintenance et de le remettre en ligne ultérieurement. Une valeur de 0 signifie toujours réessayer les travailleurs dans un état d'erreur sans délai d'attente.

Cependant, il existe d'autres conditions d'échec qui ne seraient pas détectées à l'aide de mod_wimporte, par exemple, IIS backend exécutant une application qui est en panne. IIS est en hausse, donc un une connexion peut être établie et une page peut être lue, c'est juste que la page sera toujours une erreur de serveur interne 500. Ici, vous devrez utiliser failonerror pour l'attraper et forcer le travailleur dans un état d'erreur.

Dans tous les cas, une fois que le travailleur est dans un état d'erreur, le trafic n'y sera pas dirigé. J'ai essayé différentes façons de consommer ce premier échec et de le réessayer, mais il semble toujours y avoir des cas où une page d'erreur revient au client.

12
David Newcomb

Il existe une propriété "ping" dans les "paramètres BalancerMember"

En lisant la documentation, il semble que "ping" défini sur 500 ms enverra une demande avant que mod_proxy ne vous dirige vers un membre BalancerMember. mod_proxy attendra 500 ms pour une réponse d'un BalancerMember, et si mod_proxy n'obtient pas de réponse, il recevra le BalancerMember dans un état d'erreur.

Je suis fatigué de l'implémenter, mais cela ne semble pas aider à diriger vers un BalancerMember en direct.

<Proxy balancer://APICluster>
    BalancerMember https://api01 route=qa-api1 ttl=5 ping=500ms
    BalancerMember https://api02 route=qa-api2 ttl=5 ping=500ms
    ProxySet lbmethod=bybusyness stickysession=ROUTEID
</Proxy>

http://httpd.Apache.org/docs/2.4/mod/mod_proxy.html

La propriété Ping indique au serveur Web de "tester" la connexion au serveur principal avant de transmettre la demande. Pour AJP, il entraîne mod_proxy_ajp à envoyer une requête CPING sur la connexion ajp13 (implémentée sur Tomcat 3.3.2+, 4.1.28+ et 5.0.13+). Pour HTTP, il provoque mod_proxy_http à envoyer un 100-Continue au backend (uniquement valable pour HTTP/1.1 - pour les backends non HTTP/1.1, cette propriété n'a aucun effet). Dans les deux cas, le paramètre est le délai en secondes pour attendre la réponse. Cette fonctionnalité a été ajoutée pour éviter les problèmes avec les backends bloqués et occupés. Cela augmentera le trafic réseau pendant le fonctionnement normal, ce qui pourrait être un problème, mais cela réduira le trafic au cas où certains des nœuds du cluster sont en panne ou occupés. En ajoutant un suffixe de ms, le retard peut également être défini en millisecondes.

0
DanFredell