Pour déployer une nouvelle version de notre site Web, nous procédons comme suit:
Ce processus est entièrement scripté et se produit assez rapidement, mais il peut toujours y avoir un temps d'arrêt de 10 à 20 secondes lorsque les anciens fichiers sont supprimés et les nouveaux fichiers déployés.
Des suggestions sur une méthode d'arrêt de 0 seconde?
Vous avez besoin de 2 serveurs et d'un équilibreur de charge. Voici les étapes:
Le fait est que, même dans ce cas, vous aurez toujours des redémarrages d'application et une perte de sessions si vous utilisez des "sessions persistantes". Si vous avez des sessions de base de données ou un serveur d'état, alors tout devrait bien se passer.
Microsoft Web Deployment Tool prend cela en charge dans une certaine mesure:
Active la prise en charge du système de fichiers transactionnels Windows (TxF). Lorsque la prise en charge TxF est activée, les opérations sur les fichiers sont atomiques; c'est-à-dire qu'ils réussissent ou échouent complètement. Cela garantit l'intégrité des données et empêche les données ou les fichiers d'exister dans un état "à mi-chemin" ou corrompu. Dans MS Deploy, TxF est désactivé par défaut.
Il semble que la transaction concerne l'intégralité de la synchronisation. En outre, TxF est une fonctionnalité de Windows Server 2008, donc cette fonctionnalité de transaction ne fonctionnera pas avec les versions antérieures.
Je pense qu'il est possible de modifier votre script pour 0-downtime en utilisant des dossiers comme versions et la métabase IIS:
Cette méthode offre les avantages suivants:
Vous pouvez obtenir un déploiement sans interruption de service sur un seul serveur en utilisant le routage des demandes d'application dans IIS comme équilibreur de charge logicielle entre deux sites locaux IIS sur différents ports. est connue sous le nom de stratégie de déploiement bleu vert où un seul des deux sites est disponible dans l'équilibreur de charge à un moment donné. Déployez sur le site qui est "down", réchauffez-le et placez-le dans l'équilibreur de charge (généralement en passant un contrôle de santé de routage de demande d'application), puis retirez le site d'origine qui était en haut, du "pool" (encore une fois en faisant échouer son contrôle de santé ).
J'ai récemment vécu cela et la solution que j'ai trouvée était d'avoir deux sites configurés en IIS et de basculer entre eux.
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 avec leur propre pool d'applications. L'un des sites fonctionne (A) et l'autre est arrêté (B). celui en direct a également l'en-tête de l'hôte en direct.
Quand il s'agit de déployer pour vivre, je publie simplement à l'emplacement du site ARRÊTÉ. Parce que je peux accéder au site B en utilisant son port, je peux préchauffer le site afin que le premier utilisateur ne provoque pas le démarrage d'une application. Puis en utilisant un fichier batch, je copie l'en-tête de l'hôte en direct vers B, arrête A et démarre B.
À l'aide de la classe ServerManager de Microsoft.Web.Administration, vous pouvez développer votre propre agent de déploiement.
L'astuce consiste à modifier le PhysicalPath de VirtualDirectory, ce qui entraîne un basculement atomique en ligne entre les anciennes et les nouvelles applications Web.
Sachez que cela peut entraîner l'exécution simultanée d'anciens et de nouveaux AppDomains!
Le problème est de savoir comment synchroniser les modifications apportées aux bases de données, etc.
En recherchant l'existence d'AppDomains avec d'anciens ou de nouveaux PhysicalPaths, il est possible de détecter quand les anciens AppDomain se sont terminés et si les nouveaux AppDomain ont démarré.
Pour forcer un AppDomain à démarrer, vous devez effectuer une demande HTTP (IIS 7.5 prend en charge la fonction de démarrage automatique)
Vous avez maintenant besoin d'un moyen de bloquer les demandes pour le nouveau AppDomain. J'utilise un mutex nommé - qui est créé et détenu par l'agent de déploiement, attendu par Application_Start de la nouvelle application Web, puis publié par l'agent de déploiement une fois les mises à jour de la base de données effectuées.
(J'utilise un fichier marqueur dans l'application Web pour activer le comportement d'attente mutex) Une fois la nouvelle application Web en cours d'exécution, je supprime le fichier marqueur.
D'accord, puisque tout le monde vote contre la réponse que j'ai écrite en 2008 * ...
Je vais vous dire comment nous le faisons maintenant en 2014. Nous n'utilisons plus de sites Web parce que 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 bien si vous avez 3 serveurs pour chaque site Web que vous gérez, mais c'est une surpuissance totale pour la plupart des sites Web.
De plus, nous ne comptons pas sur le dernier assistant de Microsoft - trop lent, et trop magique caché, et trop enclin à changer de nom.
Voici comment nous procédons:
Nous avons une étape de post-construction qui copie les DLL générées dans un dossier "bin-pub".
Nous utilisons Beyond Compare (qui est excellent **) pour vérifier et synchroniser les fichiers modifiés (via FTP car cela est largement pris en charge) jusqu'au serveur de production
Nous avons une URL sécurisée sur le site Web contenant un bouton qui copie tout dans "bin-pub" vers "bin" (en prenant d'abord une sauvegarde pour permettre une restauration rapide). À ce stade, l'application redémarre d'elle-même. Ensuite, notre ORM vérifie s'il y a des tables ou des colonnes qui doivent être ajoutées et les crée.
Ce n'est qu'un temps d'arrêt de quelques millisecondes. Le redémarrage de l'application peut prendre une seconde ou deux, mais pendant le redémarrage, les demandes sont mises en mémoire tampon, il n'y a donc aucun temps d'arrêt.
L'ensemble du processus de déploiement prend de 5 secondes à 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 répertoire différent, mais uniquement le dossier bin. Vous avez également un contrôle total sur le processus et savez exactement ce qui change.
** Nous observons toujours rapidement les changements que nous déployons - comme une dernière vérification de dernière minute, nous savons donc quoi tester et si quelque chose se casse, nous sommes prêts. Nous utilisons Beyond Compare car il vous permet de différencier facilement des fichiers via FTP. Je ne ferais jamais ça sans BC, vous n'avez aucune idée de ce que vous écrasez.
* Faites défiler vers le bas pour le voir :( BTW, je ne recommanderais plus les sites Web car ils sont plus lents à créer et peuvent mal tomber avec des fichiers temporaires à moitié compilés. Nous les avons utilisés dans le passé car ils permettaient un fichier plus agile fichier par fichier Très rapide pour résoudre 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).
Les seules méthodes sans interruption de service auxquelles je peux penser consistent à héberger sur au moins 2 serveurs.
Voici comment je le fais:
Configuration système minimale absolue:
1 serveur avec
Flux de travail:
démarrer la transaction myupdate
try
Web-Service: Tell all applications on all web-servers to go into primary read-only mode
Application switch to primary read-only mode, and responds
Web sockets begin notifying all clients
Wait for all applications to respond
wait (custom short interval)
Web-Service: Tell all applications on all web-servers to go into secondary read-only mode
Application switch to secondary read-only mode (data-entry Fuse)
Updatedb - secondary read-only mode (switches database to read-only)
Web-Service: Create backup of database
Web-Service: Restore backup to new database
Web-Service: Update new database with new schema
Deploy new application to apt-repository
(for windows, you will have to write your own custom deployment web-service)
ssh into every machine in array_of_new_webapps
run apt-get update
then either
apt-get dist-upgrade
OR
apt-get install <packagename>
OR
apt-get install --only-upgrade <packagename>
depending on what you need
-- This deploys the new application to all new chroots (or servers/VMs)
Test: Test new application under test.domain.xxx
-- everything that fails should throw an exception here
commit myupdate;
Web-Service: Tell all applications to send web-socket request to reload the pages to all clients at time x (+/- random number)
@client: notify of reload and that this causes loss of unsafed data, with option to abort
@ time x: Switch load balancer from array_of_old_webapps to array_of_new_webapps
Decomission/Recycle array_of_old_webapps, etc.
catch
rollback myupdate
switch to read-write mode
Web-Service: Tell all applications to send web-socket request to unblock read-only mode
end try
Pour développer la réponse de sklivvz, qui reposait sur une sorte d'équilibreur de charge (ou simplement une copie de secours sur le même serveur)
Il est possible d'introduire un peu de test de fumée, en créant un instantané/copie de base de données, mais ce n'est pas toujours faisable.
Si possible et si nécessaire, utilisez des "différences de routage", telles que des URL de locataire différentes: (customerX.myapp.net) ou différents utilisateurs, pour déployer d'abord sur un groupe inconnu de cobayes. Si rien n'échoue, libérez tout le monde.
Étant donné que les migrations de base de données sont impliquées, revenir à une version précédente est souvent impossible.
Il existe des moyens de rendre les applications plus agréables dans ces scénarios, comme l'utilisation de files d'attente d'événements et de mécanismes de lecture, mais comme nous parlons de déployer des modifications sur quelque chose qui est en cours d'utilisation, il n'y a vraiment aucun moyen infaillible.
Je raffinerais un peu la réponse de George, comme suit, pour un seul serveur:
L'étape 4 entraîne le recyclage du processus de travail IIS IIS).
Ce n'est que zéro temps d'arrêt si vous n'utilisez pas de sessions InProc; utilisez plutôt le mode SQL si vous le pouvez (encore mieux, évitez complètement l'état de la session).
Bien sûr, c'est un peu plus impliqué lorsqu'il y a plusieurs serveurs et/ou des changements de base de données ....