Skip to main content

Déploiement sans interruption de service

POUR AGENT IAChatGPTClaude

Méthodologie et mécanismes d'ingénierie pour mettre à jour les services de production sans interrompre le service aux utilisateurs, sans rompre les connexions TCP existantes et sans générer d'erreurs HTTP 502/503.

1. Vue d'ensemble du concept et problématique système

Le redémarrage primitif des services via le processus (systemctl restart app ou docker restart container) engendre un temps d'arrêt technique (Downtime). Pendant les 5 à 30 secondes nécessaires à l'initialisation de l'environnement d'exécution, à la connexion aux bases de données et à la compilation JIT du nouveau processus :

  • Toutes les requêtes HTTP actives sont interrompues en pleine transmission de données.
  • Le load balancer ou le reverse proxy renvoie aux utilisateurs des erreurs 502 Bad Gateway ou 504 Gateway Timeout.
  • Les transactions utilisateur (paiements, sauvegarde d'état, génération LLM) restent dans un état semi-corrompu.

Le Zero-Downtime Deployment élimine ce temps d'arrêt grâce à l'orchestration du cycle de vie des processus. La nouvelle version de l'application s'exécute parallèlement à l'ancienne. Le trafic ne bascule qu'une fois que la nouvelle instance a répondu avec succès aux sondes de Health Check, tandis que l'ancienne instance termine correctement toutes les opérations initiées en mode Graceful Shutdown.

Phase 1 : Version active v1.0
[Clients] ---> [Reverse Proxy / Nginx] ---> [Conteneur v1.0 (Actif)]

Phase 2 : Lancement de v1.1 et vérification d'intégrité (Healthcheck)
[Clients] ---> [Reverse Proxy / Nginx] ---> [Conteneur v1.0 (Actif)]
                                             [Conteneur v1.1 (Démarrage... /healthz : 200 OK)]

Phase 3 : Bascule du trafic et arrêt gracieux de v1.0
[Clients] ---> [Reverse Proxy / Nginx] ---> [Conteneur v1.1 (Actif)]
                                       \---> [Conteneur v1.0 (Finalisation des requêtes actives... SIGTERM)]

Phase 4 : Terminaison (v1.0 désactivé)
[Clients] ---> [Reverse Proxy / Nginx] ---> [Conteneur v1.1 (Actif)]

2. Taxonomie architecturale et modèle mental

Stratégies de mise à jour sans interruption :

  1. Blue/Green Deployment :
    • Duplication complète de la couche infrastructurelle.
    • Bascule atomique immédiate du trafic au niveau Nginx, Traefik ou DNS/ALB.
    • Fiabilité maximale et rollback simplifié, mais nécessite une double réserve de mémoire vive et de ressources hôte.
  2. Rolling Update :
    • Les conteneurs sont mis à jour séquentiellement, un par un ou par groupes.
    • Maintient une capacité constante du cluster (par exemple, minimum 3 répliques opérationnelles sur 4).
    • Économie de ressources matérielles ; standard par défaut dans Kubernetes et Docker Swarm.
  3. Canary Release :
    • La nouvelle version reçoit un pourcentage fixe et faible du trafic réel (par exemple, 2-5 %) ou est destinée à un groupe interne spécifique d'utilisateurs.
    • Suivi des métriques système (Error Rate, Latency). Si aucune anomalie n'est détectée, la part du trafic augmente progressivement jusqu'à 100 %.

3. Pipeline technique et mécanique interne

Implémentation du Graceful Shutdown en Node.js / TypeScript

Le processus doit intercepter correctement les signaux du système d'exploitation SIGTERM et SIGINT :

import express from "express";
import http from "http";

const app = express();
let isShuttingDown = false;

// Healthcheck ендпоінт для оркестратора
app.get("/healthz", (req, res) => {
  if (isShuttingDown) {
    // Сигнал балансувальнику не направляти сюди нові запити
    return res.status(503).json({ status: "shutting_down" });
  }
  return res.status(200).json({ status: "healthy" });
});

const server = http.createServer(app);
server.listen(3000);

// Перехоплення сигналу завершення від Docker / systemd
process.on("SIGTERM", () => {
  console.log("SIGTERM received. Starting graceful shutdown...");
  isShuttingDown = true;

  // 1. Припиняємо прийом нових HTTP-з'єднань
  server.close(async () => {
    console.log("Closed all remaining HTTP connections.");

    try {
      // 2. Закриваємо пули з'єднань з базами даних та Redis
      await dbPool.end();
      await redisClient.quit();
      console.log("Infrastructure connections closed. Exiting process.");
      process.exit(0);
    } catch (err) {
      console.error("Error during teardown:", err);
      process.exit(1);
    }
  });

  // 3. Запобіжник (Fail-safe): примусове завершення при зависанні сокетів
  setTimeout(() => {
    console.error("Forced termination: active connections timed out.");
    process.exit(1);
  }, 20000); // 20 секунд ліміту
});

Configuration du Healthcheck dans Docker Compose

Pour garantir la bascule du trafic par l'orchestrateur, le paramètre de vérification de santé est configuré comme suit :

services:
  api:
    image: my-company/api:v1.2.0
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"]
      interval: 5s
      timeout: 3s
      retries: 3
      start_period: 10s
    stop_grace_period: 30s # Час на виконання Graceful Shutdown

4. Scénarios d'ingénierie pratiques en production

01. Déploiement via Coolify sans interruption du trafic

La plateforme Coolify utilise un reverse proxy Traefik intégré. Lors du clic sur Deploy, elle construit une nouvelle image Docker, lance un nouveau conteneur sur un port aléatoire, interroge son endpoint de healthcheck et ne reconfigure le routage Traefik à chaud qu'après confirmation de la validité, avant d'envoyer un signal SIGTERM à la réplique ancienne.

02. Rechargement à chaud de la configuration Nginx (nginx -s reload)

Lors de la mise à jour des certificats SSL ou de l'ajout de nouvelles configurations upstream, le processus master de Nginx lance un nouveau jeu de worker-processus avec la nouvelle configuration. Les anciens workers cessent d'accepter de nouvelles connexions, terminent la transmission des fichiers actifs aux clients courants, puis se terminent eux-mêmes sans perdre un seul paquet.

03. Déploiement de migrations de base de données sans verrouillage de tables dans PostgreSQL

Lors de l'ajout d'index à de grandes tables (millions de lignes), la commande standard CREATE INDEX bloque la table en écriture (EXCLUSIVE LOCK), ce qui entraîne le gel de la file d'attente des requêtes. Les ingénieurs utilisent l'option CREATE INDEX CONCURRENTLY, qui construit l'index en arrière-plan sans bloquer les opérations parallèles de lecture et d'écriture.


5. Pièges courants, erreurs typiques et sécurité

  1. Absence de stop_grace_period dans Docker : Par défaut, Docker accorde seulement 10 secondes au conteneur pour traiter le SIGTERM, après quoi il envoie un SIGKILL mortel (tue immédiatement le processus). Si une requête longue vers un LLM ou un webhook de paiement dure 12 secondes, l'opération sera interrompue avec corruption des données. Augmentez la limite à 30–60 secondes.
  2. Incompatibilité des versions de code avec la base de données : Tenter de renommer une colonne de table (ALTER TABLE users RENAME COLUMN email TO contact_email) casse instantanément la vieille version du code qui continue de fonctionner pendant le déploiement en parallèle. Appliquez toujours le pattern Expand-and-Contract en deux releases distinctes.
  3. Endpoints de Health Check faussement positifs : Si l'endpoint /healthz vérifie la disponibilité de toutes les API tierces externes (par exemple, OpenAI ou Twitter API) et que celles-ci ralentissent temporairement, l'orchestrateur considérera votre propre service comme mort et entrera dans une boucle infinie de redémarrages (CrashLoopBackOff / Healthcheck Storm), détruisant un système de production fonctionnel. La sonde liveness ne doit vérifier que le processus local.
/ Questions fréquentesSchema.org FAQPage

FAQ: Déploiement sans interruption de service

Le déploiement Blue-Green consiste à créer une seconde copie entièrement isolée de l'environnement (Green) en parallèle avec l'environnement actif (Blue). Une fois les tests réussis, le trafic est basculé instantanément au niveau du load balancer (de 0 % à 100 %), et le rollback consiste simplement à inverser cette bascule en une seconde. La mise à jour progressive (Rolling Update) renouvelle les conteneurs ou instances par lots successifs (par exemple, 25 % à la fois), économisant ainsi des ressources matérielles, mais exigeant une compatibilité ascendante/descendante des versions durant la phase de coexistence transitoire.
/ Liens internes
Tous les termes