137 votes

Comment déployer une application ASP.NET sans interruption de service ?

Pour déployer une nouvelle version de notre site web, nous procédons comme suit :

  1. Fermez le nouveau code, et téléchargez-le sur le serveur.
  2. Sur le serveur live, supprimez tout le code live du répertoire IIS website.
  3. Extrayez le fichier zip du nouveau code dans le répertoire IIS maintenant vide.

Ce processus est entièrement programmé et se déroule assez rapidement, mais il peut y avoir un temps d'arrêt de 10 à 20 secondes lorsque les anciens fichiers sont supprimés et que les nouveaux fichiers sont déployés.

Des suggestions sur une méthode de temps d'arrêt de 0 seconde ?

0 votes

Cela ne devrait-il pas être sur ServerFault ?

53 votes

Peut-être, mais ServerFault n'existait pas en septembre 2008.

3 votes

IIS peut-il pointer vers un dossier symlink ? La modification du lien symbolique entraînera-t-elle le recyclage du processus IIS ?

87voto

Sklivvz Points 16412

Vous avez besoin de 2 serveurs et d'un équilibreur de charge. Voici les étapes à suivre :

  1. Tourner tout le trafic sur le serveur 2
  2. Déployer sur le serveur 1
  3. Serveur de test 1
  4. Tourner tout le trafic sur le serveur 1
  5. Déployer sur le serveur 2
  6. Serveur de test 2
  7. Tourner le trafic sur les deux serveurs

Le problème est que, même dans ce cas, vous aurez toujours des redémarrages d'applications et des pertes de sessions si vous utilisez des "sessions collantes". Si vous avez des sessions de base de données ou un serveur d'état, tout devrait bien se passer.

4 votes

Vous pouvez également configurer l'équilibreur de charge de manière à ce qu'il prenne en charge les sessions existantes pour un serveur donné, mais n'en accepte pas de nouvelles. Cela vous permet d'éviter d'abandonner des sessions. Cette technique nécessite cependant d'attendre que les sessions se terminent, et en général vous voudrez script ceci.

44 votes

Cette méthode a tendance à échouer lorsque le code roll comporte des modifications structurelles de la base de données. Une fois que vous aurez mis à jour la base de données du serveur 1, le serveur 2 explosera. Vous pouvez maintenant sauvegarder/restaurer la base de données pour les tests sur le serveur 1, mais vous devez alors trier les données qui ont changé dans la base de données active pendant que la copie parallèle était en cours d'exécution.

0 votes

@EBarr : Faites en sorte que la version 2 pointe vers une BD différente. De cette façon, vous pouvez garder le serveur 2 sur la version 1 tout en mettant à jour le serveur 1.

61voto

George Tsiokos Points 1008

El Outil de déploiement Web de Microsoft soutient cela dans une certaine mesure :

Active le fichier transactionnel de Windows (TxF) de Windows. Lorsque la prise en charge de TxF est activé, les opérations sur les fichiers sont atomiques, c'est-à-dire qu'elles réussissent ou échouent complètement. Cela garantit que les données l'intégrité des données et empêche les données ou les fichiers données ou les fichiers dans un état "à moitié" ou état corrompu. Dans MS Deploy, TxF est désactivé par défaut.

Il semble que la transaction concerne la totalité de la synchronisation. De plus, TxF est une fonctionnalité de Windows Server 2008, donc cette fonctionnalité de transaction ne fonctionnera pas avec les versions antérieures.

Je crois qu'il est possible de modifier votre script pour un temps de descente de 0 en utilisant les dossiers comme versions et la métabase IIS :

  • pour un chemin/url existant :
  • Copier le nouveau site web (ou le site modifié) sur le serveur sous
    • \web\app\v2.1\
  • Modifier la métabase de IIS pour changer le chemin du site web
    • de \web\app\2.0\
    • à \web\app\v2.1\

Cette méthode offre les avantages suivants :

  • En cas de problème avec la nouvelle version, vous pouvez facilement revenir à la version 2.0.
  • Pour le déploiement sur plusieurs serveurs physiques ou virtuels, vous pourriez utiliser votre script pour le déploiement de fichiers. Une fois que tous les serveurs disposent de la nouvelle version, vous pouvez modifier simultanément les métabases de tous les serveurs à l'aide de l'outil Microsoft Web Deployment Tool.

5 votes

J'ai mis en œuvre cette approche en adaptant notre déploiement powershell scripts. Vous pouvez voir la partie du scripts qui change le dossier du site IIS ici : stackoverflow.com/questions/330608/ Merci pour l'indication.

17 votes

Malheureusement, cette méthode ne tient pas compte des changements structurels de la BD. Une fois que vous mettez à jour la BD pour la v2.1, la v.2.0 explose.

8 votes

L'utilisation de TxF est exagérée ici, IMO. Cela ne fait pas de mal d'avoir les v2.0 et v2.1 dans le système de fichiers en même temps. Le grand changement se produit lorsque la v2.1 est mise en ligne, et à ce moment-là, la transaction TxF a été validée. Le temps d'arrêt nul est dû à la façon dont IIS passe d'un ancien AppPool à un nouveau, et non à TxF.

9voto

Rob King Points 51

J'ai connu cette situation récemment et la solution que j'ai trouvée a été d'avoir deux sites configurés dans IIS et de passer de l'un à l'autre.

Pour ma configuration, j'avais un répertoire web pour chaque site A et B comme ceci : c : \Intranet\Live A \Interface c : \Intranet\Live B \Interface

Dans IIS, j'ai deux sites identiques (mêmes ports, authentification, etc.), chacun ayant son propre pool d'applications. Un des sites est en cours d'exécution (A) et l'autre est arrêté (B). Le site en cours d'exécution a également l'en-tête d'hôte en cours d'exécution.

Lorsqu'il s'agit de déployer en direct, je publie simplement à l'emplacement du site STOPPED. Comme je peux accéder au site B en utilisant son port, je peux préchauffer le site pour que le premier utilisateur ne provoque pas le démarrage de l'application. Ensuite, à l'aide d'un fichier batch, je copie l'en-tête de l'hôte en direct vers B, j'arrête A et je démarre B.

1 votes

Cela permet de limiter les temps d'arrêt dus à la copie des fichiers, mais présente le même problème que @Sklivvz -- dès que le code roll apporte des modifications structurelles à la base de données, le site explose.

0 votes

Cela me semble également être la méthode intuitive, mais pourquoi n'existe-t-il pas une méthode simple et intégrée pour le faire ?

3 votes

@Ebarr alors ne faites pas de changements destructifs de sql. Par exemple, si vous devez supprimer une colonne, faites-le dans la prochaine version lorsqu'elle ne sera plus utilisée par A ou B.

8voto

mike nelson Points 3819

Puisque tout le monde rejette la réponse que j'ai écrite en 2008*...

Je vais vous dire comment nous procédons maintenant en 2014. Nous n'utilisons plus de sites Web car nous utilisons maintenant ASP.NET MVC.

Nous n'avons certainement pas besoin d'un équilibreur de charge et de deux serveurs pour le faire. C'est très bien si vous avez 3 serveurs pour chaque site web que vous gérez, mais c'est totalement excessif pour la plupart des sites web.

De plus, nous ne nous fions pas au dernier assistant de Microsoft - trop lent, avec trop de magie cachée, et trop enclin à changer de nom.

Voici comment nous procédons :

  1. Nous avons une étape post-construction qui copie les DLLs générées dans un dossier 'bin-pub'.

  2. Nous utilisons Beyond Compare (qui est excellent**) pour vérifier et synchroniser les fichiers modifiés (par FTP parce que c'est largement supporté) sur le serveur de production.

  3. Nous disposons d'une URL sécurisée sur le site web contenant un bouton qui copie tout ce qui se trouve dans "bin-pub" vers "bin" (en prenant d'abord une sauvegarde pour permettre un retour en arrière rapide). À ce stade, l'application redémarre elle-même. Ensuite, notre ORM vérifie si des tables ou des colonnes doivent être ajoutées et les crée.

Cela ne représente que quelques millisecondes de temps d'arrêt. Le redémarrage de l'application peut prendre une ou deux secondes, mais les demandes sont mises en mémoire tampon pendant le redémarrage, de sorte que le temps d'arrêt est effectivement nul.

L'ensemble du processus de déploiement prend entre 5 secondes et 30 minutes, selon le nombre de fichiers modifiés et le nombre de modifications à examiner.

De cette façon, vous n'avez pas à copier un site Web entier dans un autre répertoire, mais seulement le dossier bin. Vous avez également un contrôle total sur le processus et savez exactement ce qui est modifié.

**Nous faisons toujours un examen rapide des changements que nous déployons - comme une double vérification de dernière minute, afin de savoir ce qu'il faut tester et si quelque chose se casse, nous sommes prêts. Nous utilisons Beyond Compare parce qu'il vous permet de comparer facilement les fichiers par FTP. Je ne ferais jamais cela sans BC, vous n'avez aucune idée de ce que vous écrasez.

*Défilez jusqu'en bas pour le voir :( BTW Je ne recommanderais plus les sites Web parce qu'ils sont plus lents à construire et peuvent se planter gravement avec des fichiers temporaires à moitié compilés. Nous les utilisions dans le passé car ils permettaient un déploiement plus agile fichier par fichier. Il est très rapide de corriger un problème mineur et vous pouvez voir exactement ce que vous déployez (si vous utilisez Beyond Compare bien sûr - sinon, oubliez-le).

0 votes

Mais vous aurez toujours des temps d'arrêt car le pool d'applications se recycle.

0 votes

Non, pas de temps d'arrêt car les demandes sont mises en mémoire tampon automatiquement par IIS pendant le redémarrage de l'application.

7voto

Jack Points 845

En utilisant la classe ServerManager de Microsoft.Web.Administration, vous pouvez développer votre propre agent de déploiement.

L'astuce consiste à modifier le PhysicalPath du VirtualDirectory, ce qui entraîne une commutation atomique en ligne entre les anciennes et les nouvelles applications web.

Soyez conscient que cela peut entraîner l'exécution en parallèle des anciens et des nouveaux domaines d'application !

Le problème est de savoir comment synchroniser les modifications apportées aux bases de données, etc.

En recherchant l'existence de domaines d'applications avec d'anciens ou de nouveaux PhysicalPaths, il est possible de détecter quand les anciens domaines d'applications sont terminés, et si les nouveaux domaines d'applications ont démarré.

Pour forcer un AppDomain à démarrer, vous devez faire une requête HTTP (IIS 7.5 supporte la fonction Autostart).

Maintenant vous avez besoin d'un moyen de bloquer les demandes pour le nouveau AppDomain. J'utilise un mutex nommé - qui est créé et possédé par l'agent de déploiement, attendu par l'Application_Start de la nouvelle application web, et ensuite libéré par l'agent de déploiement une fois que les mises à jour de la base de données ont été faites.

(J'utilise un fichier marqueur dans l'application web pour activer le comportement d'attente du mutex). Une fois que la nouvelle application web fonctionne, je supprime le fichier marqueur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X