Guide pratique du load balancing avec nginx
Beaucoup de développeurs n’utilisent nginx que comme proxy inverse + serveur de fichiers statiques, mais en réalité, nginx est un load balancer logiciel très puissant.
Si vous gérez vous-même les serveurs, maîtriser nginx peut considérablement améliorer la stabilité et les performances de votre service lorsqu’il subit un pic de trafic.
Dans cet article, destiné aux développeurs débutants à intermédiaires, nous aborderons :
- Le concept de load balancing
- La configuration de load balancing avec nginx
- Les algorithmes (round robin, least_conn, ip_hash, etc.)
- La vérification de l’état de santé (health check)
- Les options fréquemment utilisées
1. Qu’est‑ce que le load balancing ?
Load balancing consiste simplement à
« Distribuer les requêtes entre plusieurs serveurs afin d’éviter qu’un seul ne soit surchargé ».
Pourquoi est‑ce nécessaire ?
- Prévention des pics de trafic * Même si les requêtes s’accumulent à un moment donné, aucun serveur ne s’arrête.
- Scalabilité horizontale * Plutôt que d’augmenter la puissance d’un seul serveur, on ajoute plusieurs serveurs pour accroître la capacité.
- Haute disponibilité * Si un serveur tombe en panne, le trafic est redirigé vers les autres.
Où se situe nginx ?
La structure typique est la suivante :
Client → nginx (load balancer / proxy inverse) → plusieurs serveurs d’applications
nginx reçoit les requêtes et les transmet à l’un des serveurs d’applications.
2. Comprendre la structure de base du load balancing avec nginx
Dans la configuration nginx, le load balancing se compose de deux parties principales.
- Bloc upstream : * Définit le pool de serveurs back‑end.
- Bloc server / location : * Indique vers quel upstream envoyer les requêtes entrantes.
Voici un exemple très simple.
http {
upstream app_backend {
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://app_backend;
# En-têtes de proxy par défaut
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Ce que signifie cette configuration
upstream app_backend- Regroupe les deux serveurs d’applications
10.0.0.101:3000et10.0.0.102:3000en un seul pool. proxy_pass http://app_backend;- Transmet la requête du client vers l’un des serveurs du pool.
- Si aucun algorithme n’est spécifié, nginx utilise round robin par défaut.
3. Types d’algorithmes de load balancing
nginx propose plusieurs stratégies de répartition. Choisir la bonne dépend de votre situation.
3.1 Round robin (par défaut)
upstream app_backend {
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
- 1ᵉre requête → serveur 1
- 2ᵉme requête → serveur 2
- 3ᵉre requête → serveur 1 …
Avantages : simple, fonctionne bien dans la plupart des cas. Inconvénients : ne tient pas compte de la charge actuelle des serveurs.
3.2 least_conn (serveur avec le moins de connexions actives)
upstream app_backend {
least_conn;
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
- Envoie la nouvelle requête vers le serveur ayant le moins de connexions actives.
- Idéal pour les services où le temps de traitement varie beaucoup entre les requêtes.
Scénarios recommandés
- Certaines requêtes sont longues, d’autres rapides.
- Les serveurs ont des spécifications similaires mais des schémas de requêtes déséquilibrés.
3.3 ip_hash (même client → même serveur)
upstream app_backend {
ip_hash;
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
- Le hash de l’adresse IP du client détermine toujours le même serveur.
- Utile pour les sessions sticky lorsqu’elles sont stockées en mémoire sur le serveur.
Avantages : garantit que les requêtes d’un même client vont toujours au même serveur. Inconvénients : l’ajout ou la suppression de serveurs peut réattribuer de nombreux clients.
3.4 Répartition pondérée (weight)
upstream app_backend {
server 10.0.0.101:3000 weight=3;
server 10.0.0.102:3000 weight=1;
}
- Le serveur 1 reçoit 3 fois plus de requêtes que le serveur 2.
- Pratique lorsqu’un serveur est plus puissant que les autres.
4. Health check et gestion des serveurs défaillants
Pour que le load balancer soit réellement intelligent, il doit pouvoir retirer automatiquement les serveurs défaillants.
nginx open‑source prend en charge les health checks passifs.
4.1 max_fails / fail_timeout
upstream app_backend {
server 10.0.0.101:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.102:3000 max_fails=3 fail_timeout=30s;
}
max_fails=3: 3 échecs consécutifs marquent le serveur comme défaillant.fail_timeout=30s: le serveur est ignoré pendant 30 s, puis réessayé.
Les échecs incluent généralement les réponses 502/503/504 ou les échecs de connexion.
4.2 proxy_next_upstream
location / {
proxy_pass http://app_backend;
proxy_next_upstream error timeout http_502 http_503 http_504;
}
- En cas d’erreur spécifiée, nginx passe à un autre serveur.
- Évitez les redondances excessives qui augmentent la latence.
5. Exemple concret : load balancing d’un service web simple
Supposons deux serveurs Node.js tournant sur le port 3000.
10.0.0.101:300010.0.0.102:3000
5.1 Configuration nginx
http {
upstream app_backend {
least_conn;
server 10.0.0.101:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.102:3000 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name myservice.com;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
}
}
}
Après rechargement, toutes les requêtes vers myservice.com sont
* reçues par nginx
* envoyées au serveur Node.js ayant le moins de connexions
* retirées automatiquement si un serveur échoue plusieurs fois.
6. Terminaison HTTPS (SSL) + load balancing
En production, on utilise presque toujours HTTPS. Le pattern le plus courant est de faire de nginx le point de terminaison SSL.
http {
upstream app_backend {
least_conn;
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
server {
listen 443 ssl;
server_name myservice.com;
ssl_certificate /etc/letsencrypt/live/myservice.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myservice.com/privkey.pem;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Redirection HTTP → HTTPS
server {
listen 80;
server_name myservice.com;
return 301 https://$host$request_uri;
}
}
- Client ↔ nginx : HTTPS
- nginx ↔ serveurs d’applications : HTTP (généralement interne)
7. Les sessions : faut‑il vraiment des sessions sticky ?
Autrefois, les sessions étaient souvent stockées en mémoire sur le serveur, ce qui nécessitait que le même client soit toujours dirigé vers le même serveur.
Avec ip_hash, on peut résoudre ce problème de façon simple, mais aujourd’hui on préfère généralement :
- Stocker les sessions dans un magasin externe (Redis, etc.)
- Utiliser des JWT pour rendre l’application stateless
En supprimant l’état au niveau de l’application, le load balancer ne fait que répartir le trafic, ce qui simplifie l’évolutivité.
8. Points de réglage fréquents
8.1 Keepalive
Réutiliser les connexions vers le back‑end améliore les performances.
upstream app_backend {
least_conn;
server 10.0.0.101:3000;
server 10.0.0.102:3000;
keepalive 32;
}
server {
location / {
proxy_pass http://app_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
keepalive 32: chaque worker maintient jusqu’à 32 connexions keepalive vers le back‑end.
8.2 Buffers et timeouts
location / {
proxy_pass http://app_backend;
proxy_buffering on;
proxy_buffers 16 16k;
proxy_busy_buffers_size 64k;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
- Un
proxy_read_timeouttrop court peut provoquer des erreurs 504. - Ajustez selon le trafic et la performance du back‑end.
9. Stratégie d’introduction du load balancing nginx (étapes)
Si votre service tourne déjà sur un seul serveur, voici une approche progressive.
- Étape 1 : introduire nginx comme proxy inverse * Client → nginx → serveur unique * Utiliser SSL, cache, fichiers statiques.
- Étape 2 : dupliquer le serveur et configurer upstream
* Ajoutez un second serveur, mettez‑les dans le bloc
upstream. - Étape 3 : health check + monitoring
*
max_fails,fail_timeout,proxy_next_upstream. * Intégrez Prometheus/Grafana ou ELK. - Étape 4 : affiner l’algorithme et les réglages
* Choisissez
least_connouweightselon le pattern. * Optimisez keepalive, buffers, timeouts.
Conclusion
nginx n’est pas seulement un proxy inverse ; il possède un load balancing robuste.
- Définissez vos pools avec
upstream. - Choisissez l’algorithme adapté (round robin, least_conn, ip_hash, weight).
- Activez les health checks et la politique de réessai.
- Terminez le SSL sur nginx et proxiez vers le back‑end en HTTP.
Avec ces éléments, vous pourrez passer d’un seul serveur à une architecture plus résiliente et performante, tout en gardant le contrôle sur la répartition du trafic.

Aucun commentaire.