BLOG | NGINX

Équilibrage de charge avec NGINX et NGINX Plus, partie 2

Vignette d'Owen Garrett
Owen Garrett
Publié le 17 mars 2014

Dans Équilibrage de charge avec NGINX et NGINX Plus, partie 1 , nous configurons un proxy HTTP simple pour équilibrer la charge du trafic sur plusieurs serveurs Web. Dans cet article, nous examinerons des fonctionnalités supplémentaires, dont certaines sont disponibles dans NGINX Plus : optimisation des performances avec keepalives , contrôles de santé , persistance de session , redirections et réécriture de contenu .

Pour plus de détails sur les fonctionnalités d’équilibrage de charge dans NGINX et NGINX Plus, consultez le Guide d’administration de NGINX Plus .

Éditeur – NGINX Plus Release 5 et versions ultérieures peuvent également équilibrer la charge des applications basées sur TCP. L'équilibrage de charge TCP a été considérablement étendu dans la version 6 par l'ajout de contrôles de santé, de reconfiguration dynamique, de terminaison SSL, etc. Dans NGINX Plus Release 7 et versions ultérieures, l'équilibreur de charge TCP présente une parité fonctionnelle complète avec l'équilibreur de charge HTTP. La prise en charge de l’équilibrage de charge UDP a été introduite dans la version 9.

Vous configurez l'équilibrage de charge TCP et UDP dans le contexte de flux au lieu du contexte http . Les directives et paramètres disponibles diffèrent quelque peu en raison des différences inhérentes entre HTTP et TCP/UDP ; pour plus de détails, consultez la documentation des modules HTTP et TCP/UDP Upstream.

Un bref aperçu

Pour récapituler, voici la configuration que nous avons construite dans l'article précédent :

server {    listen 80;

    location / {
        proxy_pass http://backend;

        # Rewrite the 'Host' header to the value in the client request,
        # or primary server name
        proxy_set_header Host $host;

        # Alternatively, put the value in the config:
        # proxy_set_header Host www.example.com;
    } 
}

upstream backend {
    zone backend 64k;  # Use NGINX Plus' shared memory
    least_conn;

    server webserver1 weight=1;
    server webserver2 weight=4;
}

Dans cet article, nous examinerons quelques méthodes simples pour configurer NGINX et NGINX Plus qui améliorent l’efficacité de l’équilibrage de charge.

Keepalive HTTP

L'activation des keepalives HTTP entre NGINX ou NGINX Plus et les serveurs en amont améliore les performances (en réduisant la latence) et réduit la probabilité que NGINX manque de ports éphémères.

Le protocole HTTP utilise des connexions TCP sous-jacentes pour transmettre des requêtes HTTP et recevoir des réponses HTTP. Les connexions HTTP keepalive permettent la réutilisation de ces connexions TCP, évitant ainsi la surcharge liée à la création et à la destruction d'une connexion pour chaque requête :

TCPKA

NGINX est un proxy complet et gère les connexions des clients (connexions keepalive frontales) et les connexions aux serveurs (connexions keepalive en amont) de manière indépendante :

NGINX maintient un « cache » de connexions keepalive (un ensemble de connexions keepalive inactives vers les serveurs en amont) et lorsqu'il doit transmettre une demande à un serveur en amont, il utilise une connexion keepalive déjà établie à partir du cache plutôt que de créer une nouvelle connexion TCP. Cela réduit la latence des transactions entre NGINX et les serveurs en amont et réduit la vitesse à laquelle les ports éphémères sont utilisés, de sorte que NGINX est capable d'absorber et d'équilibrer la charge de gros volumes de trafic. En cas de pic de trafic important, le cache peut être vidé et dans ce cas, NGINX établit de nouvelles connexions HTTP vers les serveurs en amont.

Avec d’autres outils d’équilibrage de charge, cette technique est parfois appelée multiplexage , regroupement de connexions , réutilisation de connexions ou OneConnect .

Vous configurez le cache de connexion keepalive en incluant les directives proxy_http_version , proxy_set_header et keepalive dans la configuration :

server {    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
     }
}

upstream backend {
    server webserver1;
    server webserver2;

    # maintain up to 20 idle connections to the group of upstream servers
    keepalive 20;
}

 

Contrôles de santé

L’activation des contrôles de santé augmente la fiabilité de votre service à charge équilibrée, réduit la probabilité que les utilisateurs finaux voient des messages d’erreur et peut également faciliter les opérations de maintenance courantes.

La fonction de contrôle de santé de NGINX Plus peut être utilisée pour détecter la défaillance des serveurs en amont. NGINX Plus sonde chaque serveur à l'aide de « transactions synthétiques » et vérifie la réponse par rapport aux paramètres que vous configurez dans la directive health_check (et, lorsque vous incluez le paramètre match , le bloc de configuration de correspondance associé) :

server {    listen 80;

    location / {
        proxy_pass http://backend;

        health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;

        # The health checks inherit other proxy settings
        proxy_set_header Host www.foo.com;
    }
}

match statusok {
    # Used for /test.php health check
    status 200;
    header Content-Type = text/html;
    body ~ "Server[0-9]+ is alive";
}

Le contrôle de santé hérite de certains paramètres de son bloc d’emplacement parent. Cela peut entraîner des problèmes si vous utilisez des variables d'exécution dans votre configuration. Par exemple, la configuration suivante fonctionne pour le trafic HTTP réel car elle extrait la valeur de l’en-tête Host de la demande client. Cela ne fonctionne probablement pas pour les transactions synthétiques utilisées par le contrôle de santé, car l'en-tête d'hôte n'est pas défini pour elles, ce qui signifie qu'aucun en-tête d'hôte n'est utilisé dans la transaction synthétique.

location / {    proxy_pass http://backend;

    # This health check might not work...
    health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;

    # Extract the 'Host' header from the request
    proxy_set_header Host $host;
}

Une bonne solution consiste à créer un bloc d’emplacement factice qui définit de manière statique tous les paramètres utilisés par la transaction de contrôle d’intégrité :

location /internal-health-check1 {    internal; # Prevent external requests from matching this location block

    proxy_pass http://backend;

    health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;

    # Explicitly set request parameters; don't use run-time variables
    proxy_set_header Host www.example.com;
}

Pour plus d'informations, consultez le Guide d'administration NGINX Plus .

Persistance de la session

Grâce à la persistance des sessions, les applications qui ne peuvent pas être déployées dans un cluster peuvent être équilibrées et mises à l'échelle de manière fiable. Les applications qui stockent et répliquent l’état de session fonctionnent plus efficacement et les performances de l’utilisateur final s’améliorent.

Certaines applications stockent parfois des informations d’état sur les serveurs en amont, par exemple lorsqu’un utilisateur place un article dans un panier virtuel ou modifie une image téléchargée. Dans ces cas, vous souhaiterez peut-être diriger toutes les demandes ultérieures de cet utilisateur vers le même serveur.

La persistance de session spécifie vers où une demande doit être acheminée, tandis que l'équilibrage de charge donne à NGINX la liberté de sélectionner le serveur en amont optimal. Les deux processus peuvent coexister grâce à la capacité de persistance de session de NGINX Plus :

   Si la demande correspond à une règle de persistance de session
utilisez ensuite le serveur cible en amont
sinon, appliquez l’algorithme d’équilibrage de charge pour sélectionner le serveur en amont

Si la décision de persistance de session échoue parce que le serveur cible n’est pas disponible, NGINX Plus prend une décision d’équilibrage de charge.

La méthode de persistance de session la plus simple est l'approche « sticky cookie », où NGINX Plus insère un cookie dans la première réponse qui identifie le serveur sticky en amont :

sticky cookie srv_id expires=1h domain=.example.com path=/;

Dans la méthode alternative « sticky route », NGINX sélectionne le serveur en amont en fonction des paramètres de requête tels que le cookie JSESSIONID :

upstream backend {
   server backend1.example.com route=a;
   server backend2.example.com route=b;

    # select first non-empty variable; it should contain either 'a' or 'b'
    sticky route $route_cookie $route_uri;
}

Pour plus d'informations, consultez le Guide d'administration NGINX Plus .

Réécriture des redirections HTTP

Réécrivez les redirections HTTP si certaines redirections sont rompues, et en particulier si vous constatez que vous êtes redirigé du proxy vers le véritable serveur en amont.

Lorsque vous utilisez un proxy vers un serveur en amont, le serveur publie l'application sur une adresse locale, mais vous accédez à l'application via une adresse différente – l'adresse du proxy. Ces adresses correspondent généralement à des noms de domaine et des problèmes peuvent survenir si le serveur et le proxy ont des domaines différents.

Par exemple, dans un environnement de test, vous pouvez adresser votre proxy directement (par adresse IP) ou en tant que localhost . Cependant, le serveur en amont peut écouter un nom de domaine réel (tel que www.nginx.com ). Lorsque le serveur en amont émet un message de redirection (en utilisant un en-tête d'état et d'emplacement 3xx ou en utilisant un en-tête d'actualisation ), le message peut inclure le domaine réel du serveur.

NGINX tente d'intercepter et de corriger les cas les plus courants de ce problème. Si vous avez besoin d'un contrôle total pour forcer des réécritures particulières, utilisez la directive proxy_redirect comme suit :

proxy_redirect http://staging.mysite.com/ http://$host/;

Réécriture des réponses HTTP

Parfois, vous devez réécrire le contenu d'une réponse HTTP. Peut-être que, comme dans l’exemple ci-dessus, la réponse contient des liens absolus qui font référence à un serveur autre que le proxy.

Vous pouvez utiliser la directive sub_filter pour définir la réécriture à appliquer :

sub_filter /blog/ /blog-staging/;
sub_filter_once off;

Un problème très courant est l’utilisation de la compression HTTP. Si le client signale qu’il peut accepter des données compressées et que le serveur compresse ensuite la réponse, NGINX ne peut pas inspecter et modifier la réponse. La mesure la plus simple consiste à supprimer l'en-tête Accept-Encoding de la requête du client en le définissant sur la chaîne vide ( "" ) :

proxy_set_header Accept-Encoding "";

Un exemple complet

Voici un modèle de configuration d’équilibrage de charge qui utilise toutes les techniques décrites dans cet article. Les fonctionnalités avancées disponibles dans NGINX Plus sont surlignées en orange.

[Éditeur – La configuration suivante a été mise à jour pour utiliser l’ API NGINX Plus pour la surveillance des activités en direct et la configuration dynamique des groupes en amont, remplaçant les modules séparés qui étaient utilisés à l’origine.]

server {
    listen 80;

    location / {
        proxy_pass http://backend;

        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Accept-Encoding "";
        proxy_redirect http://staging.example.com/ http://$host/;

        # Rewrite the Host header to the value in the client request
        proxy_set_header Host $host;

        # Replace any references inline to staging.example.com
        sub_filter http://staging.example.com/ /;
        sub_filter_once off;
    }

    location /internal-health-check1 {
        internal; # Prevent external requests from matching this location block
        proxy_pass http://backend;
        health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;
        # Explicitly set request parameters; don't use runtime variables
        proxy_set_header Host www.example.com;
    }
 
upstream backend {
    zone backend 64k; # Use NGINX Plus' shared memory
    least_conn;
    keepalive 20;

    # Apply session persistence for this upstream group
    sticky cookie srv_id expires=1h domain=.example.com path=/servlet;

    server webserver1 weight=1; 
    server webserver2 weight=4; 
}

match statusok {
    # Used for /test.php health check
    status 200;
    header Content-Type = text/html;
    body ~ "Server[0-9]+ is alive";
}

server {
    listen 8080;
    root /usr/share/nginx/html;

    location = /api {
        api write=on; # Live activity monitoring and
                      # dynamic configuration of upstream groups

        allow 127.0.0.1; # permit access from localhost
        deny all;        # deny access from everywhere else
    }
}

Essayez par vous-même toutes les excellentes fonctionnalités d’équilibrage de charge de NGINX Plus : démarrez votre essai gratuit de 30 jours dès aujourd’hui ou contactez-nous pour discuter de vos cas d’utilisation .


« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."