Lorsque vous retirez un serveur backend ou qu'il échoue à un contrôle d'intégrité, les connexions établies ne sont pas immédiatement interrompues. La fermeture brutale de ces connexions peut perturber les requêtes en cours et empêcher l'arrêt gracieux des services. Pour éviter ce problème, utilisez la fonctionnalité de vidange de connexion (connection draining) d'Application Load Balancer (ALB). Lorsqu'un serveur backend est retiré ou échoue à un contrôle d'intégrité, la vidange de connexion maintient les connexions existantes actives pendant une période configurée. Une fois le délai d'expiration écoulé, ALB ferme les connexions pour garantir un arrêt gracieux.
Cas d'utilisation
La vidange de connexion s'applique aux deux scénarios suivants.
Retrait d'un serveur backend : avant de retirer un serveur backend, définissez un délai d'expiration de vidange de connexion plus long pour permettre aux requêtes en cours de se terminer.
Échec du contrôle d'intégrité : pour un serveur backend qui échoue à un contrôle d'intégrité, définissez un délai d'expiration plus court afin de fermer rapidement les connexions défectueuses et d'empêcher les clients de recevoir des erreurs de connexion.
Étant donné que les deux scénarios partagent la même configuration de vidange de connexion, définissez un délai d'expiration adapté à vos besoins métier.
Retirer un serveur backend
La figure suivante illustre un exemple. Lorsque vous retirez le serveur backend ECS01, ALB cesse de lui envoyer de nouvelles requêtes. ECS01 traite alors uniquement les requêtes en cours et n'accepte aucune nouvelle requête.
Si la vidange de connexion est désactivée, ECS01 ferme la session uniquement après le traitement de toutes les requêtes en cours.
-
Si la vidange de connexion est activée et qu'un délai d'expiration est défini :
Si le serveur backend retiré ECS01 a des requêtes en cours, ALB ferme les sessions existantes sur ECS01 une fois le délai d'expiration de la vidange de connexion écoulé.
Si le serveur backend retiré ECS01 n'a aucune requête en cours ni connexion active, ALB termine immédiatement le processus de retrait sans attendre l'expiration du délai de vidange de connexion.
Si le serveur backend retiré ECS01 est en train de traiter une requête lorsque le processus de retrait se termine, la connexion est interrompue et le client reçoit une réponse d'erreur 500. Par exemple, si le délai d'expiration de la vidange de connexion est fixé à 15 secondes mais que le temps de traitement de la requête sur ECS01 est de 30 secondes, la connexion est interrompue avant qu'ECS01 ne puisse envoyer une réponse. Dans ce cas, le client reçoit une réponse d'erreur 500.
RemarqueSi vous rajoutez ECS01 au groupe de serveurs, cela n'affecte pas les sessions déjà en cours de vidange. ECS01 reste dans l'état de vidange — traitant uniquement les requêtes en cours — jusqu'à ce que les sessions existantes soient fermées. ALB ferme ces sessions à l'expiration du délai de vidange de connexion.
La figure suivante montre les transitions d'état d'ECS01 après son retrait d'un groupe de serveurs avec la vidange de connexion activée.
Échec du contrôle d'intégrité
Lorsque le serveur backend ECS01 échoue à un contrôle d'intégrité, ALB cesse de lui envoyer de nouvelles requêtes. ECS01 traite alors uniquement les requêtes en cours et n'accepte aucune nouvelle requête.
Si la vidange de connexion est désactivée, ECS01 reste dans cet état jusqu'à ce qu'il réussisse le contrôle d'intégrité. Une fois le contrôle réussi, il commence à accepter de nouvelles requêtes.
-
Si la vidange de connexion est activée et qu'un délai d'expiration est défini :
ALB ferme les sessions existantes sur ECS01 une fois le délai d'expiration de la vidange de connexion écoulé.
Si vous mettez à jour le groupe de serveurs (par exemple, en modifiant la configuration d'ECS01), son état de connexion ne change pas ; il continue de traiter uniquement les requêtes en cours. Même si ECS01 réussit un contrôle d'intégrité après la mise à jour, ALB ferme toujours ses sessions existantes à l'expiration du délai de vidange de connexion.
RemarqueUne fois le délai d'expiration de la vidange de connexion écoulé et les sessions fermées par ALB, ECS01 ne peut accepter de nouvelles requêtes que s'il réussit le contrôle d'intégrité. S'il continue d'échouer, il n'acceptera pas de nouvelles requêtes.
La vidange de connexion est déclenchée uniquement par les échecs de contrôle d'intégrité causés par des problèmes de service backend, et non par les échecs résultant de mises à jour de configuration.
La figure suivante montre les transitions d'état d'ECS01 après l'échec d'un contrôle d'intégrité.
Vous pouvez configurer la vidange de connexion en fonction de votre scénario métier. Cette rubrique utilise le Scénario 1 : Retirer un serveur backend comme exemple pour démontrer comment configurer la terminaison des sessions WebSocket et HTTP.
Notes d'utilisation
Seules les instances ALB Standard et compatibles WAF prennent en charge la vidange de connexion, tandis que les instances ALB Basic ne la prennent pas en charge.
Les groupes de serveurs Function Compute ne prennent pas en charge la vidange de connexion.
La vidange de connexion est effective pour les sessions WebSocket et HTTP. Pour les sessions HTTP, nous vous recommandons de définir le délai d'expiration de la vidange de connexion sur une valeur supérieure au délai d'expiration de la demande de connexion ALB afin d'éviter la fermeture inattendue des requêtes. Les valeurs de délai d'expiration par défaut suivent déjà cette recommandation. Pour savoir comment définir le délai d'expiration de la demande de connexion, consultez Ajouter un écouteur HTTP.
Prérequis
Une instance ALB Standard ou compatible WAF a été créée, et un groupe de serveurs de type Serveur a été créé pour l'instance ALB. Cette rubrique utilise une instance ALB Standard comme exemple. Pour plus d'informations, consultez Créer une instance ALB et Créer et gérer un groupe de serveurs.
Vous avez configuré un écouteur HTTP sur le port
80pour l'instance ALB et l'avez associé au groupe de serveurs. Pour plus d'informations, consultez Ajouter un écouteur HTTP.Vous avez créé deux serveurs backend, ECS01 et ECS02. Pour plus d'informations, consultez Créer une instance à l'aide de l'assistant.
-
Vous avez ajouté ECS02 au groupe de serveurs et il est accessible depuis le client. Pour plus d'informations, consultez Utiliser ALB pour réaliser l'équilibrage de charge des services IPv4 et Utiliser ALB pour réaliser l'équilibrage de charge des services IPv6.
RemarqueCette rubrique utilise un système d'exploitation Alibaba Cloud Linux 3.2104 64 bits comme client. Assurez-vous que Python est installé à la fois sur votre client et sur le serveur backend ECS01. Si Python n'est pas installé, consultez le site officiel de Python pour obtenir des instructions. Cette rubrique utilise Python 3.x comme exemple.
Dans cette rubrique, ECS02 est le serveur backend qui gère le trafic de production. Si vous disposez déjà d'un tel serveur backend, vous n'avez pas besoin d'en créer un.
Procédure
Après avoir activé la vidange de connexion et défini un délai d'expiration, cette rubrique explique comment ALB gère les requêtes pour les sessions WebSocket et HTTP dans différents états de vidange de connexion.
Sessions WebSocket
Étape 1 : Activer la vidange de connexion
Un groupe de serveurs a été créé en tant que prérequis. Cette étape montre comment activer la vidange de connexion pour un groupe de serveurs existant. Vous pouvez également activer cette fonctionnalité lors de sa création.
Connectez-vous à la console ALB.
Dans la barre de navigation supérieure, sélectionnez la région où le groupe de serveurs est déployé.
Dans le volet de navigation de gauche, choisissez ALB > Server Groups.
Sur la page Server Groups, recherchez le groupe de serveurs cible et cliquez sur son ID.
Sous l'onglet Details, dans la section Basic Information, cliquez sur Modify Basic Information.
Dans la boîte de dialogue Modify Basic Information, cliquez sur Advanced Settings et activez Connection Draining.
Définissez le Timeout Period sur 300 secondes et cliquez sur Save.
Étape 2 : Vérifier les résultats
Configurer le serveur
Connectez-vous à l'instance ECS01. Pour plus d'informations, consultez Méthodes de connexion.
-
Exécutez les commandes suivantes pour créer et accéder à un répertoire WebSocket :
mkdir WebSocket cd WebSocket -
Exécutez la commande suivante pour installer les dépendances :
pip install tornado pip install websocket-client -
Exécutez la commande suivante pour modifier le fichier de configuration server.py :
vim server.py-
Appuyez sur
ipour passer en mode édition et ajoutez les configurations suivantes pour démarrer un service WebSocket :#!/usr/bin/env python3 # encoding=utf-8 import tornado.websocket import tornado.ioloop import tornado.web from datetime import datetime # WebSocket handler class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Time:", formatted_time, "WebSocket connection opened") def on_message(self, message): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Time:", formatted_time, "Received message:", message) self.write_message("Server received your message: " + message) def on_close(self): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Time:", formatted_time, "WebSocket connection closed") # Routing application = tornado.web.Application([ (r"/websocket", WebSocketHandler), ]) if __name__ == "__main__": print("WebSocket Server Start on 8080 ...") application.listen(8080) tornado.ioloop.IOLoop.current().start() Après avoir modifié le fichier de configuration, appuyez sur la touche
Esc, saisissez:wq, puis appuyez sur Entrée pour enregistrer et fermer le fichier.
-
-
Accédez au répertoire où se trouve server.py et exécutez la commande suivante pour démarrer le service WebSocket :
python3 server.pyLa réponse suivante indique que le service backend WebSocket est démarré.
Websocket Server Start on 8080 ...
Ajouter ECS01 au groupe de serveurs
Connectez-vous à la console ALB.
Dans la barre de navigation supérieure, sélectionnez la région où le groupe de serveurs est déployé.
Dans le volet de navigation de gauche, choisissez ALB > Server Groups.
Sur la page Server Groups, recherchez le groupe de serveurs cible et cliquez sur Modify Backend Server dans la colonne Actions.
Sous l'onglet Backend Servers, cliquez sur Add Backend Server. Dans le panneau Add Backend Server, sélectionnez ECS01 et cliquez sur Next.
À l'étape Ports/Weights, sélectionnez l'instance ECS01, définissez le port sur
8080, puis cliquez sur OK.
Configurer le client
-
Connectez-vous au client et ouvrez l'interface de ligne de commande (CLI). Exécutez les commandes suivantes pour créer et accéder à un répertoire WebSocket :
mkdir WebSocket cd WebSocket -
Exécutez la commande suivante pour installer les dépendances :
pip install websocket-client -
Exécutez la commande suivante pour modifier le fichier client.py :
vim client.py-
Appuyez sur
ipour passer en mode édition et ajoutez les configurations suivantes pour démarrer un client WebSocket afin d'accéder au service :#!/usr/bin/env python3 # encoding=utf-8 import websocket import time from datetime import datetime def on_message(ws, message): print("Received message from server:", message) if __name__ == "__main__": ws = websocket.WebSocket() ws.connect("ws://<domain_name>:80/websocket") # Replace <domain_name> with your actual domain name. print("WebSocket connection opened") try: while True: current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Sending time:", formatted_time) ws.send("Hello, Server!") result = ws.recv() on_message(ws, result) time.sleep(1) except Exception: print("WebSocket connection closed") Après avoir modifié le fichier de configuration, appuyez sur la touche
Esc, saisissez:wq, puis appuyez sur Entrée pour enregistrer et fermer le fichier.
-
-
Accédez au répertoire où se trouve client.py et exécutez la commande suivante pour accéder au serveur backend ECS01 :
python3 client.pyLa réponse suivante indique que l'accès a réussi.
WebSocket connection opened Sending time: 2024-04-28 17:00:53 Received message from server: Server received your message: Hello, Server! Sending time: 2024-04-28 17:00:54 Received message from server: Server received your message: Hello, Server!Le serveur backend ECS01 renvoie la réponse suivante.
WebSocket Server Start on 8080 ... Time: 2024-04-28 17:00:53 WebSocket connection opened Time: 2024-04-28 17:00:53 Received message: Hello, Server! Time: 2024-04-28 17:00:54 Received message: Hello, Server!
Retirer le serveur backend
Définissez le délai d'expiration de la vidange de connexion avant de retirer le serveur backend.
Connectez-vous à la console ALB.
Dans la barre de navigation supérieure, sélectionnez la région où le groupe de serveurs est déployé.
Dans le volet de navigation de gauche, choisissez ALB > Server Groups.
Recherchez le groupe de serveurs cible et cliquez sur son ID.
Cliquez sur l'onglet Backend Servers, recherchez le serveur backend cible ECS01, puis cliquez sur Remove dans la colonne Actions.
Dans la boîte de dialogue Remove, cliquez sur OK.
Attendre la vidange de connexion
Le paramètre Timeout Period est défini sur 300 secondes. Les résultats du test montrent qu'ALB interrompt la session environ 300 secondes après le retrait d'ECS01.
Dans les résultats du test, la différence de temps entre l'ouverture et la fermeture de la connexion WebSocket sur le serveur ECS01 est de 330 secondes. Le délai d'expiration de la vidange de connexion, qui correspond à la durée écoulée entre le retrait du serveur backend ECS01 et la fermeture de la connexion WebSocket, est d'environ 300 secondes.
-
Le client renvoie la réponse suivante.
Sending time: 2024-04-28 17:06:23 Received message from server: Server received your message: Hello, Server! Sending time: 2024-04-28 17:06:24 WebSocket connection closed -
L'instance de serveur ECS01 renvoie la réponse suivante.
Time: 2024-04-28 17:06:22 Received message: Hello, Server! Time: 2024-04-28 17:06:23 Received message: Hello, Server! Time: 2024-04-28 17:06:23 WebSocket connection closed
Sessions HTTP
Dans les scénarios HTTP, la réponse reçue par le client varie en fonction des paramètres du délai d'expiration de la vidange de connexion, du délai d'expiration de la demande de connexion et du temps de traitement du serveur backend.
Si le délai d'expiration de la vidange de connexion est inférieur au temps de traitement du serveur backend, la connexion est interrompue avant qu'ECS01 n'envoie une réponse. Dans ce cas, le client reçoit une réponse d'erreur 500.
Si le temps de traitement du serveur backend est supérieur au délai d'expiration de la demande de connexion, la requête vers ECS01 expire. Dans ce cas, le client reçoit une réponse d'erreur 504.
Cette rubrique utilise un délai d'expiration de la vidange de connexion de 15 secondes et un temps de traitement du serveur backend de 30 secondes comme exemple. Dans ce scénario, la connexion est interrompue avant qu'ECS01 ne termine l'envoi de la réponse, et le client reçoit une réponse d'erreur 500.
Une erreur 504 n'est pas renvoyée car le délai d'expiration de la demande de connexion (60 secondes, défini à l'étape Étape 2) est supérieur au temps de traitement du serveur backend (30 secondes). Une erreur 500 se produit plutôt parce que le délai d'expiration de la vidange de connexion (15 secondes) est inférieur au temps de traitement du serveur.
Cette rubrique utilise la fonction
time.sleepdu code Python pour simuler le temps de traitement du serveur backend.
Étape 1 : Activer la vidange de connexion
Un groupe de serveurs a été créé en tant que prérequis. Cette étape montre comment activer la vidange de connexion pour un groupe de serveurs existant. Vous pouvez également activer cette fonctionnalité lors de sa création.
Connectez-vous à la console ALB.
Dans la barre de navigation supérieure, sélectionnez la région où le groupe de serveurs est déployé.
Dans le volet de navigation de gauche, choisissez ALB > Server Groups.
Sur la page Server Groups, recherchez le groupe de serveurs cible et cliquez sur son ID.
Sous l'onglet Details, dans la section Basic Information, cliquez sur Modify Basic Information.
Dans la boîte de dialogue Modify Basic Information, cliquez sur Advanced Settings et activez Connection Draining.
Définissez le Timeout Period sur 15 secondes et cliquez sur Save.
Étape 2 : Définir le délai d'expiration de la requête ALB
Connectez-vous à la console ALB.
Dans la barre de navigation supérieure, sélectionnez la région où l'instance ALB est déployée.
Sur la page Instances, recherchez l'instance ALB cible et cliquez sur son ID.
Cliquez sur l'onglet Listener, recherchez l'écouteur HTTP cible, puis cliquez sur son ID.
Dans la zone Basic Information, cliquez sur Modify Listener.
Dans la boîte de dialogue Modify Listener, cliquez sur Modify à côté de Advanced Settings.
Définissez le paramètre Connection Request Timeout sur 60 secondes (valeur par défaut) et cliquez sur Save.
Étape 3 : Configurer la résolution DNS
Pour la production, nous vous recommandons de mapper un nom de domaine personnalisé au nom de domaine de l'instance ALB en créant un enregistrement CNAME.
Dans le volet de navigation de gauche, choisissez .
Sur la page Instances, copiez le nom DNS de l'instance ALB créée.
-
Suivez ces étapes pour ajouter un enregistrement CNAME.
RemarqueSi votre nom de domaine est enregistré auprès d'un fournisseur autre qu'Alibaba Cloud, vous devez ajouter le nom de domaine à la console Alibaba Cloud DNS avant de pouvoir configurer la résolution DNS. Pour plus d'informations, consultez Gérer les noms de domaine. Si votre nom de domaine est enregistré auprès d'Alibaba Cloud, procédez comme suit.
Connectez-vous à la console Alibaba Cloud DNS.
Sur la page Public Zone, recherchez le nom de domaine cible et cliquez sur Settings dans la colonne Operations.
Sur la page Settings, cliquez sur Add Record.
-
Dans le panneau Add Record, configurez l'enregistrement CNAME en définissant les paramètres suivants, puis cliquez sur OK.
Paramètre
Description
Record Type
Sélectionnez CNAME dans la liste déroulante.
Hostname
Le préfixe de votre nom de domaine. Ce tutoriel utilise @.
RemarquePour utiliser un domaine racine, définissez le hostname sur
@.Query Source
Sélectionnez Default.
Record Value
Saisissez le nom DNS de l'instance ALB que vous avez copié.
TTL
Le Time to live (TTL) correspond à la durée pendant laquelle un enregistrement DNS est mis en cache sur un serveur DNS. Utilisez la valeur par défaut.
Étape 4 : Vérifier les résultats
Configurer le serveur
Connectez-vous à l'instance ECS01. Pour plus d'informations, consultez Méthodes de connexion.
-
Exécutez les commandes suivantes pour créer et accéder à un répertoire HTTP :
mkdir http cd http -
Exécutez la commande suivante pour modifier le fichier de configuration http_server.py :
vim http_server.py-
Appuyez sur
ipour passer en mode édition et ajoutez les configurations suivantes pour démarrer un service de serveur HTTP :#!/usr/bin/env python3 # encoding=utf-8 from http.server import SimpleHTTPRequestHandler, HTTPServer from datetime import datetime import time class DelayedHTTPRequestHandler(SimpleHTTPRequestHandler): def do_GET(self): current_time = datetime.now() formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") print("Time:", formatted_time, "GET request received. Responding after a 30-second delay....") time.sleep(30) # Use the time.sleep function to simulate the processing time of the backend server. SimpleHTTPRequestHandler.do_GET(self) PORT = 8080 server = HTTPServer(("", PORT), DelayedHTTPRequestHandler) print(f"Serving HTTP on 0.0.0.0 port {PORT} (http://0.0.0.0:{PORT}/) ...") server.serve_forever() Après avoir modifié le fichier de configuration, appuyez sur la touche
Esc, saisissez:wq, puis appuyez sur Entrée pour enregistrer et fermer le fichier.
-
-
Accédez au répertoire où se trouve http_server.py et exécutez la commande suivante pour démarrer le service de serveur HTTP :
python3 http_server.pyLa réponse suivante indique que le service backend du serveur HTTP est démarré.
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
Ajouter ECS01 au groupe de serveurs
Connectez-vous à la console ALB.
Dans la barre de navigation supérieure, sélectionnez la région où le groupe de serveurs est déployé.
Sur la page Server Groups, recherchez le groupe de serveurs cible et cliquez sur Modify Backend Server dans la colonne Actions.
Sous l'onglet Backend Servers, cliquez sur Add Backend Server. Dans le panneau Add Backend Server, sélectionnez ECS01 et cliquez sur Next.
À l'étape Ports/Weights, sélectionnez l'instance ECS01, définissez le port sur
8080, puis cliquez sur OK.
Configurer le client
-
Connectez-vous au client et ouvrez la CLI. Exécutez la commande suivante pour accéder au serveur backend ECS01 :
curl http://<domain_name>:80/ -vLa réponse suivante indique qu'ALB peut accéder au service backend.
* About to connect() to www.example.com port 80 (#0) * Trying 10.X.X.225... * Connected to www.example.com (10.X.X.225) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: www.example.com > Accept: */*Le serveur renvoie la réponse suivante.
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... Time: 2024-02-07 13:57:33 Received a GET request. Responding after a 30-second delay....
Retirer le serveur backend
Définissez le délai d'expiration de la vidange de connexion avant de retirer le serveur backend.
Connectez-vous à la console ALB.
Dans la barre de navigation supérieure, sélectionnez la région où le groupe de serveurs est déployé.
Dans le volet de navigation de gauche, choisissez ALB > Server Groups.
Recherchez le groupe de serveurs cible et cliquez sur son ID.
Cliquez sur l'onglet Backend Servers, recherchez le serveur backend cible ECS01, puis cliquez sur Remove dans la colonne Actions.
Dans la boîte de dialogue Remove, cliquez sur OK.
Attendre la vidange de connexion
Les résultats du test montrent que le client reçoit une réponse d'erreur 500 lorsque le délai d'expiration de la vidange de connexion défini pour ALB est inférieur au temps de traitement du serveur backend.
* About to connect() to www.example.com port 80 (#0)
* Trying 10.X.X.224...
* Connected to www.example.com (10.XX.XX.224) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.example.com
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Date: Wed, 07 Feb 2024 06:02:24 GMT
< Content-Type: text/html
< Content-Length: 186
< Connection: close
< Via: HTTP/1.1 SLB.87
<
<html>
<head><title>500 Internal Server Error</title></head>
<body bgcolor="white">
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Closing connection 0
Documentation connexe
Pour activer la vidange de connexion lors de la création d'un groupe de serveurs, consultez Créer et gérer un groupe de serveurs.
Pour déployer des services de manière gracieuse, vous pouvez activer la fonctionnalité de démarrage lent (slow start). Pour plus d'informations, consultez Configurer le démarrage lent.
Pour en savoir plus sur l'utilisation des protocoles WebSocket et HTTP avec ALB, consultez Ajouter un écouteur HTTP et Utiliser le protocole WebSocket avec ALB pour diffuser des informations en temps réel.