Diagramme de load balancer : couche 4 ou couche 7, health checks et algorithmes

Le load balancing en dessin : couche 4 ou 7, deux niveaux, algorithmes du round robin au least request, health checks, draining et sessions collantes.

· Fondateur et développeur

Publié le

Diagramme de load balancer : couche 4 ou couche 7, health checks et algorithmes

« Mettez un load balancer devant » est la phrase la plus courante en conception de systèmes, et elle cache une poignée de décisions qui comptent en production : à quelle couche il travaille, comment il choisit un backend, comment il sait qu'un backend est sain, et ce qu'il advient des requêtes en cours quand on en retire un.

Cet article passe en revue ces décisions et dessine la configuration à deux niveaux à laquelle aboutissent la plupart des grands déploiements : un balancer de couche 4 devant une flotte de proxys de couche 7.

Couche 4 ou couche 7

Couche 4 Couche 7
Voit Adresses IP, ports, connexions TCP ou UDP Requêtes HTTP : hôte, chemin, en-têtes, cookies
Répartit Des connexions Des requêtes
TLS Le laisse passer, ou le termine Le termine en général
Peut router selon Port, adresse source Chemin, hôte, en-tête, méthode
Sait aussi faire Très haut débit, faible latence Retries, timeouts, réécritures, authentification, limitation de débit
Exemples Load balancers réseau des clouds, IPVS, balancers de type Maglev Envoy, NGINX, HAProxy en mode HTTP, load balancers applicatifs des clouds

La différence qui fait mal : un balancer de couche 4 répartit des connexions, pas des requêtes. Avec HTTP/2 ou gRPC, un client ouvre une seule connexion de longue durée et envoie des milliers de requêtes dessus, qui atterrissent toutes sur le même backend. Bien répartir du gRPC demande un proxy de couche 7 ou un load balancing côté client.

Pourquoi deux niveaux

Les grandes configurations empilent souvent les deux. Un niveau de couche 4 détient les adresses IP publiques, absorbe les afflux de connexions et répartit les connexions sur une flotte de proxys de couche 7 en hachant chaque flux. Les proxys terminent le TLS, appliquent les règles de routage et répartissent les requêtes une à une sur les pools de backends.

Chaque niveau évolue indépendamment : la couche 4 selon les paquets et les connexions, la flotte de proxys selon les requêtes et les handshakes TLS. Les séparer limite aussi le rayon d'impact, car une mauvaise modification de configuration des proxys touche les proxys derrière un niveau, pas les adresses auxquelles se connectent les utilisateurs. Et comme les proxys sont sans état et partagent une seule configuration, en ajouter un revient simplement à ajouter de la capacité.

Algorithmes de répartition

Algorithme Comment il choisit Adapté à Attention à
Round robin Le backend suivant, à tour de rôle Backends identiques, requêtes similaires Les requêtes lentes s'accumulent sur les backends lents
Round robin pondéré Round robin, au prorata des poids Tailles d'instances mixtes, bascules progressives Les poids sont statiques
Least connections Le moins de connexions ouvertes Connexions de longue durée Demande un état global dans le balancer
Least request (deux choix aléatoires) En tirer deux au hasard, envoyer au moins occupé La plupart des services HTTP Demande le nombre de requêtes par backend
Hachage cohérent Hachage d'une clé, comme l'ID utilisateur Caches, affinité Charge inégale avec des clés chaudes

Le least request à deux choix aléatoires est un bon choix par défaut pour les services HTTP. La documentation des load balancers d'Envoy le décrit : tirer deux hôtes au hasard (deux par défaut) et envoyer la requête à celui qui a le moins de requêtes actives. Les travaux de Mitzenmacher et d'autres montrent que c'est presque aussi bon que de vérifier chaque backend, sans en payer le coût. Le hachage cohérent, comme le ring hash ou l'algorithme Maglev, garde la même clé sur le même backend et ne déplace qu'une petite part des clés quand les backends changent, ce que veulent les caches.

Health checks

Un balancer doit cesser d'envoyer du trafic aux backends qui ne peuvent pas le servir. Deux mécanismes travaillent ensemble :

  • Checks actifs : le balancer appelle un endpoint de santé, par exemple GET /healthz toutes les 5 secondes, et retire un backend après un certain nombre d'échecs consécutifs.
  • Checks passifs (détection des valeurs aberrantes) : le balancer observe les vraies réponses, écarte un backend qui renvoie des erreurs ou dépasse les timeouts, puis le réintègre après une période de refroidissement.

Rendez l'endpoint de santé honnête mais peu coûteux. S'il vérifie chaque dépendance, une seule base lente rend tous les backends malades en même temps et le balancer n'a plus nulle part où envoyer le trafic. Vérifiez ce dont cette instance a besoin pour servir des requêtes, et laissez les dépendances partagées à la gestion d'erreurs de l'application.

Draining et sessions collantes

Quand un backend est retiré pour un déploiement ou une réduction de capacité, il doit cesser de recevoir de nouvelles requêtes mais terminer celles en cours. Configurez une période de draining (les balancers cloud parlent de deregistration delay) plus longue que votre requête normale la plus lente, et faites en sorte que l'application refuse tout nouveau travail à l'arrêt.

Les sessions collantes (sticky sessions) envoient un utilisateur vers le même backend à chaque fois, en général grâce à un cookie. Elles aident quand l'état vit dans la mémoire d'un serveur, et nuisent à tout le reste : charge inégale, sessions perdues quand un backend meurt, déploiements plus difficiles. Déplacez l'état de session dans un stockage partagé et désactivez l'affinité partout où c'est possible.

Au-delà d'une région

Tout ce qui précède se passe dans un seul site. Répartir les utilisateurs entre régions est une couche à part : un routage par DNS qui répond avec la région saine la plus proche (routage par latence ou par géolocalisation), ou l'anycast, où de nombreux sites annoncent la même adresse IP et où le routage Internet amène chaque utilisateur vers un site proche. Le load balancing global choisit la région ; les deux niveaux de cet article choisissent le serveur. Faites remonter les signaux de santé, pour qu'une région dont les proxys n'atteignent plus leurs pools cesse de recevoir des utilisateurs au lieu de leur renvoyer des erreurs.

Le diagramme d'architecture

Les clients résolvent un nom DNS et se connectent en TCP 443 à un load balancer de couche 4, qui répartit les connexions par hachage de flux sur deux proxys de couche 7 identiques. Ceux-ci routent /api/orders vers le pool orders, /api/search vers le pool search, /static vers un bucket.

10 composants · 7 connexions

Ouvrir dans Archboard
Contenu du diagramme
  • Clients
  • DNS: one name
  • Layer 4 load balancer
  • Layer 7 proxy 1
  • Layer 7 proxy 2
  • Orders pool: 6 instances
  • Search pool: 4 instances
  • Static files bucket
  • Proxy fleet, same config
  • resolve
  • TCP 443
  • flow hash
  • /api/orders
  • /api/search
  • /static
Deux niveaux de load balancing. Un load balancer de couche 4 répartit les connexions TCP sur une flotte de proxys de couche 7 ; les proxys terminent le TLS et routent chaque requête HTTP par chemin vers le bon pool, avec least request et health checks.

Comment le lire :

  • À gauche : les clients résolvent un nom DNS et ouvrent des connexions TCP sur le port 443 vers le load balancer de couche 4.
  • Au milieu : le niveau de couche 4 répartit les connexions sur la flotte de proxys par hachage de flux. Le cadre montre que chaque proxy exécute la même configuration.
  • À droite : les proxys terminent le TLS et routent chaque requête par chemin : /api/orders et /api/search vers leurs pools, /static vers un bucket.
  • Le bloc Markdown contient la table de routage, l'algorithme de chaque pool et les réglages des health checks, des détails qui ne vivent d'habitude que dans un fichier de configuration.

Ce qu'il faut annoter sur un diagramme de load balancer

  • La couche et le protocole à chaque saut : TCP 443, HTTP/2, gRPC.
  • L'endroit où le TLS est terminé. Il décide ce que chaque niveau peut voir et où vivent les certificats.
  • L'algorithme de chaque pool, et la clé de hachage si vous hachez.
  • Le chemin, l'intervalle et le seuil des health checks.
  • Les réglages de draining et d'affinité, s'il y en a.

Le diagramme d'architecture d'une API gateway couvre les fonctions de couche 7 qui s'ajoutent au routage, le diagramme d'ingress Kubernetes montre les mêmes idées à l'intérieur d'un cluster, et le diagramme de topologie réseau place les load balancers dans le réseau plus large.

Le construire dans Archboard

  1. Connectez-vous avec Google ou GitHub et créez un diagramme.
  2. Ajoutez une Personne du pack Modèle C4 pour les clients, ainsi qu'un DNS et un Répartiteur de charge du pack Réseau.
  3. Ajoutez un Cadre du pack Base pour la flotte de proxys, avec deux nœuds Conteneur à l'intérieur.
  4. Ajoutez deux nœuds Instance de calcul et un nœud Stockage objet du pack Cloud pour les pools et le bucket.
  5. Annotez les arêtes avec les protocoles et les routes, et ajoutez un bloc Markdown du pack Base avec la table de routage et les health checks.

L'exemple utilise 10 nœuds de diagramme et reste dans les limites de l'offre Free.

FAQ

Quelle est la différence entre un load balancer de couche 4 et un de couche 7 ? Un balancer de couche 4 distribue des connexions TCP ou UDP sans regarder leur contenu. Un balancer de couche 7 comprend le HTTP : il peut donc router selon le chemin ou l'hôte et répartir les requêtes une à une.

Quel algorithme de load balancing utiliser ? Le least request à deux choix aléatoires est un excellent choix par défaut pour le HTTP. Utilisez le hachage cohérent quand une même clé doit atteindre le même backend, comme pour les caches.

Pourquoi mon service gRPC envoie-t-il tout le trafic vers un seul pod ? Parce que gRPC utilise des connexions HTTP/2 de longue durée et qu'un balancer de couche 4 répartit des connexions, pas des requêtes. Placez un proxy de couche 7 entre les deux ou utilisez un load balancing côté client.

Que doit vérifier un endpoint de health check ? Que cette instance peut servir des requêtes : le processus tourne et ses propres ressources critiques sont disponibles. Évitez de vérifier des dépendances partagées qui feraient échouer tous les backends à la fois.

Les sessions collantes sont-elles une bonne idée ? Seulement quand l'état ne peut pas quitter le serveur. Elles provoquent une charge inégale et des sessions perdues en cas de panne ; un stockage de session partagé est en général préférable.

Commencez gratuitement — un siège, sans carte bancaire.

Articles associés

← Retour au blog

Ouvrez un canevas en une minute

Connectez-vous avec Google ou GitHub. Gratuit pour un siège. Passez à un forfait supérieur quand l’équipe vous rejoint.