Mettre à jour le site Web .NET sans recharger


13

J'ai utilisé pour développer des sites Web dans PHPet ASP classicet si quelque chose devait être changé. Vous pouvez simplement modifier un ou plusieurs fichiers et personne ne le remarquera vraiment. Peut-être que quelqu'un demanderait le fichier modifié pendant le téléchargement, mais c'est comme une demi-seconde de marge. Pour la plupart des petits sites, ce n'est pas un problème.

Mais les derniers sites sont créés avec C# MVCet lorsque vous apportez des modifications au code, vous devez reconstruire votre site Web et télécharger les DLLfichiers modifiés . Mais lorsque vous modifiez vos DLLfichiers, il redémarre votre site Web et réinitialise tous les actifs sessions. Il doit également tout recharger et avec de grands sites, il peut prendre quelques minutes pour tout charger. Tous ceux qui naviguent sur le site le remarqueront et devront se reconnecter.

Les mises à jour majeures du site ne sont pas si courantes, ce n'est donc pas un problème. Mais nous avons régulièrement de "petites" mises à jour pour les promotions. Comme 'Remplissez ce formulaire et obtenez trois mois d'abonnement gratuit' ou 'Les 10 premiers à télécharger une image de ... recevront un prix'. Je pense que vous aurez la dérive. Certaines promotions sont similaires et pourraient être gérées avec un module qui affiche les bonnes informations en fonction des paramètres, mais il nécessite souvent un code personnalisé.

Je pensais à un système où chaque promotion est son propre DLLfichier basé sur une interface, puis je charge DLLdynamiquement à l'aide de Type.GetType, Activator.CreateInstanceet InvokeMember. Bien que cela puisse fonctionner, je me demande si c'est la bonne façon de procéder.

Donc ma question: comment mettre à jour un .NETsite à la volée, sans recharger tout le site et sans session (comme le pool d'applications de recyclage).


En réponse à votre commentaire généreux: les grands sites Web sur lesquels je travaille gèrent les petites modifications du code de la même manière qu'ils gèrent les grandes modifications du code: via des équilibreurs de charge et des sessions hors processus - car tout le code déployé pour vivre doit passer par un processus de révision / approbation et nous ne pouvons pas simplement déposer du code sur les serveurs. Je suppose que nos définitions de «grand» peuvent ne pas correspondre;)
Zhaph - Ben Duguid

Réponses:


11

Regardez dans "Initialisation des applications" IIS 7.5, Windows 2008 R2 (plus difficile à configurer) IIS 8, Windows 2012

L'initialisation de l'application permet à toute application (pool d'applications et non site) de redémarrer pour se chevaucher et utiliser l'ancienne, tout en exécutant l'application précédente tout en réchauffant le démarrage de la nouvelle application. Une fois la nouvelle application lancée (déterminée par les URL que vous pouvez définir), elle commencera à utiliser la nouvelle application et fermera la précédente. L'utilisation de l'initialisation des applications en conjonction avec des méthodes pour garantir que la session demeure pendant les redémarrages du pool d'applications peut permettre à votre site de redémarrer de manière transparente. (Zhaph a une bonne note sur la clé machine.)

En plus des liens ci-dessus pour la configuration de l'initialisation de l'application, vous allez vouloir regarder ce qui déclenche un redémarrage du site - puisque le redémarrage du site n'utilise pas l' initialisation de l' application, le redémarrage du site ne sera pas transparent.

Vous pouvez configurer IIS afin qu'une mise à jour de DLL ne déclenche pas immédiatement un redémarrage du site, ni des modifications de web.config (valeurs ChangeNotification élevées sur httpRuntime et les fichiers de configuration externes, selon votre site).

Le résultat final est que vous pouvez mettre à jour les DLL / code sans redémarrer le site, puis forcer un redémarrage de l' application qui utilisera le réchauffement d'arrière-plan AppInitialization pour la modification transparente du code.

Faire ces choses en concert fonctionne très bien pour des redémarrages fluides.


Un bon ensemble d'étapes là-bas - certainement quelque chose à considérer :)
Zhaph - Ben Duguid

Cela ressemble à ce que je cherchais. Je vais essayer et le configurer. Merci
Hugo Delsing

@HugoDelsing J'espère que cela fonctionne très bien pour vous.
jeffreypriebe

Merci, c'est ce que j'ai fini par utiliser et cela fonctionne très bien.
Hugo Delsing

@HugoDelsing Heureux d'apprendre que cela a également fonctionné pour vous.
jeffreypriebe

5

Il y a plusieurs façons de gérer ce que vous demandez et quelques aspects différents de votre question:

Gérez les petites mises à jour pour les promotions

Ce que vous recherchez vraiment ici, c'est un système de gestion de contenu ou similaire qui vous permet de modifier le contenu à la volée (pensez à Wordpress / Drupal ou d'un point de vue .NET N2 CMS, Umbraco, Orchard, etc.), mais là sont des choses que vous pourriez essayer si vous n'avez pas suivi cette voie.

Parce qu'ASP.NET ne se recharge vraiment que si vous touchez certains types de fichiers (web.config (s), le contenu des dossiers /bin/et /app_code/principalement) - et a une limite configurable pour «d'autres changements de fichiers» (essentiellement une fois que vous avez modifié afin de nombreux fichiers au sein de votre site, le pool d'applications redémarrera - NumRecompilesBeforeAppRestart) vous pourriez envisager de faire quelque chose dans lequel vous recherchez dans un dossier différent des .htmlfichiers statiques (c'est-à-dire ) que vous extrayez et affichez si nécessaire, ou utilisez la LoadControlméthode qui prend un chemin de chaîne pour un .ascxcontrôle utilisateur et le charge dynamiquement - la façon dont vous déterminez lequel afficher est une question différente plus adaptée à StackOverflow - mais je recommanderais une solution basée sur une convention de dénomination.

Vous pouvez également envisager d'utiliser quelque chose comme le Managed Extensibility Framework (MEF - qui fait partie intégrante du .NET Framework depuis la version 4) qui vous permet d'écrire une architecture basée sur un plugin et de spécifier un dossier en dehors de votre /bin/répertoire à surveiller. nouveaux .DLL - bien que je n'aie pas essayé cela pour voir si cela évitera le problème de redémarrage de l'application, je l'ai utilisé à bon escient dans un environnement Web pour ajouter des fonctionnalités communes à un site.

Si cela ne fait pas appel, la seule autre option à laquelle je peux penser serait d'ajouter les contrôles comme "code-in-front" comme nous l'avons fait dans ASP classique - c'est-à-dire avec un <script runat="server">bloc au lieu d'une classe "code-behind" compilée qui contient la logique pour exécuter le contrôle - cela supprimera la nécessité d'un changement de DLL, au détriment de la première perte de performances lors de la compilation du contrôle à la volée - encore une fois, vous devrez équilibrer cela avec le NumRecompilesBeforeAppRestartsi vous fais beaucoup de petits changements.

Comment puis-je conserver des sessions lors des redémarrages de l'application?

Il s'agit probablement d'un problème plus facile à résoudre et qui comprend trois étapes clés:

  1. Configurer la MachineKey (IIS7, mais vaut toujours pour 8) pour être une valeur constante plutôt que AutoGenerate- cela signifie que lorsque l'AppPool recycle, il utilisera la même clé, et pourra ainsi décrypter les cookies de session, l'état d'affichage, etc. d'avant le recyclage.
  2. Soit configurer un serveur d' état ou configurer une base de données pour tenir l' état de session .
  3. Basculez de l'utilisation InProcvers StateServerou SQLServerdans l'élément SessionState dans votre web.config.

De cette façon, vous aurez des sessions persistantes qui survivent au redémarrage d'une application. Cependant, ceux-ci ne sont pas "gratuits" - tout ce que vous stockez dans la session doit maintenant être sérialisable, et vous obtiendrez une légère baisse des performances car chaque chargement de page nécessitera désormais des trajets réseau supplémentaires pour obtenir, et potentiellement libérer les données de session.

Cependant, si vous êtes dans une position où il faut "plusieurs minutes" pour que l'application redémarre après un déploiement, vous voudrez peut-être envisager de passer à un environnement à charge équilibrée, ou au moins à une configuration Staging / Live remplaçable à chaud (tel que celui fourni par Azure / AWS / etc.) - De cette façon, vous pouvez mettre un serveur hors ligne pendant que vous le mettez à jour ou le préparer avec le nouveau code, puis échangez-le - à condition que vous ayez pris les mesures nécessaires pour résoudre le problème partagé sessions (voir ci-dessus), cela fonctionnera correctement sans impact sur vos utilisateurs.


Merci pour votre longue réponse. Malheureusement CMSce n'est pas ce que je veux. Je ne veux pas modifier le contenu, je veux modifier le code. La partie sur les sessions n'était qu'un exemple. Le changer ne résoudra pas le problème de l'arrêt du site pendant une minute ou deux lors du rechargement des DLLfichiers. La MEFpartie était intéressante, mais est une solution tierce au système auquel je pensais. Donc +1 pour l'effort, mais malheureusement ce n'est pas vraiment une réponse à ma question.
Hugo Delsing

1
J'ai mis à jour ma réponse pour répondre à quelques-uns de ces points: MEF a été publié par MS et fait partie intégrante du framework .NET depuis la v4. Vous pouvez essayer d'utiliser le code en façade pour vos nouveaux contrôles, ou adopter une configuration à charge équilibrée / mise en scène en direct qui permettrait de mettre un serveur en marche et de l'échanger.
Zhaph - Ben Duguid

1
J'ai décrit une solution alternative utilisant l'initialisation d'application. L'avantage est que tout le code et la configuration du serveur sont «normaux» sans équilibrage de charge spécial ni contrôle de chargement dynamique, ce qui simplifie votre environnement d'exécution. Bien sûr, une configuration d'équilibrage de charge / de mise en scène en direct peut être utile pour d'autres raisons.
jeffreypriebe
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.