Aspnetcore: IIS -> Verrouiller le fichier DLL de l'application .NET Core

CrĂ©Ă© le 7 juil. 2016  Â·  114Commentaires  Â·  Source: dotnet/aspnetcore

Lorsque j'essaie de remplacer le fichier DLL d'application .NET Core Ă  l'aide de FTP sur le serveur de production IIS, le fichier est verrouillĂ© et ne peut pas ĂȘtre Ă©crasĂ©.

Pour dĂ©ployer une nouvelle version, je dois arrĂȘter l'application dans IIS pour libĂ©rer le verrou, puis l'Ă©craser.
Il n'est pas possible de dĂ©ployer sans arrĂȘter l'application.

affected-medium area-servers bug servers-iis severity-nice-to-have

Commentaire le plus utile

👍

Ne pas soutenir le recyclage avec chevauchement est une régression.

Tous les 114 commentaires

Voir app_offline.htm: https://docs.asp.net/en/latest/hosting/aspnet-core-module.html#asp -net-core-module-app-offline-htm

Si vous souhaitez une maniĂšre PowerShell de le faire, vous pouvez utiliser les applets de commande IIS Admin: https://technet.microsoft.com/en-us/library/ee790599.aspx

Stop-WebAppPool -Name $appPoolName

... deploy ...

Start-WebAppPool -Name $appPoolName

Merci pour l'explication @Tratcher .
Je ne sais pas si cela fait partie de vos plans, mais cela a fonctionné pour le précédent ASP.NET MVC, je pense?
Avez-vous l'intention de mettre en Ɠuvre cette fonctionnalitĂ© ou non?

@GuardRex Je ne peux pas le faire car il s'agit d'un environnement d'hĂ©bergement partagĂ© et je n'ai pas l'autorisation d'arrĂȘter AppPool

Pouvez-vous faire fonctionner simplement avec msdeploy.exe et Azure? Si je comprends bien, le site Web doit ĂȘtre redĂ©marrĂ© pour Ă©viter le verrouillage des fichiers. -enableRule:AppOffline fonctionne mais l'ensemble du site Web est hors ligne pendant quelques minutes, ce qui n'est pas une excellente expĂ©rience utilisateur, d'autant plus que nous dĂ©ployons quelques fois par jour.

Voir Ă©galement http://stackoverflow.com/q/40276582/14131

@chuchuva peut-ĂȘtre, mais toute magie a un coĂ»t. Les versions prĂ©cĂ©dentes d'ASP.NET effectuaient des clichĂ©s instantanĂ©s compliquĂ©s pour contourner les problĂšmes de verrouillage de fichiers.

Magique ou pas, ça a bien fonctionné. Cela me manque un peu maintenant aprÚs la migration vers ASP.NET Core ...

D'accord avec @HarelM. Nous avons rencontrĂ© des problĂšmes avec cela, de nos dĂ©ploiements automatisĂ©s Ă  l'expĂ©rience de l'utilisateur final. Nous sommes passĂ©s du dĂ©ploiement d'environ 10 fois par jour avec l'ancien MVC Ă  peut-ĂȘtre un dĂ©ploiement quotidien la nuit et en acceptant que les personnes utilisant l'application Core soient ennuyĂ©es lorsque nous la mettrons hors ligne. Bien que ce ne soit pas un obstacle au spectacle, cela ajoute des frictions Ă  l'adoption de Core.

👍

Ne pas soutenir le recyclage avec chevauchement est une régression.

Est-il prĂ©vu de revoir cette fonctionnalitĂ© et de la mettre sur la feuille de route? Il est trĂšs peu pratique / peu convivial d'exiger de tout le monde qui dĂ©ploie un site Web .Net Core de mettre en Ɠuvre manuellement une stratĂ©gie de crĂ©neau intermĂ©diaire s'il souhaite prendre en charge les dĂ©ploiements sans temps d'arrĂȘt.

Cette fonctionnalité rendrait la transition vers les sites Web .Net Core beaucoup plus fluide pour de nombreuses personnes et permettrait une adoption plus rapide des sites Web .Net Core.

Nous aimerions également le savoir. Mettre un app_offline.htm dans le répertoire des applications ne fonctionne pas.

Je viens juste de réaliser cette «fonctionnalité» aprÚs avoir déplacé un certain nombre de sites vers AspNetCore. Je ne peux pas croire qu'il soit jugé acceptable de mettre vos sites hors ligne pendant quelques minutes à chaque fois que vous souhaitez publier!

C'est déjà assez pour moi en tant que chef d'une petite équipe - ceux qui pratiquent l'intégration continue à grande échelle évitent-ils AspNetCore? Il n'y a aucun moyen qu'ils puissent mettre leur site hors ligne pendant des minutes toutes les heures pour le republier!

DĂ©ployez-vous utiliser FTP ou xcopying? Ou utilisez-vous webdeploy?

Je publie via webdeploy sur IIS.

Nous travaillons actuellement Ă  ce problĂšme en supprimant d'abord le fichier web.config (en tuant effectivement l'application), mais ce n'est pas vraiment une solution acceptable Ă  long terme.

@DaleMckeown idĂ©alement avec un flux de travail d'intĂ©gration continue, vous auriez plusieurs serveurs derriĂšre un Ă©quilibreur de charge. Vous tiriez ensuite un serveur, le mettiez Ă  jour, le remettiez en place et passiez au suivant. Bien sĂ»r, ce n'est pas toujours possible (comme dans notre cas), vous devrez donc vivre avec quelques minutes d'arrĂȘt. Dans notre cas, l'application est sauvegardĂ©e dans les 30 secondes, ce n'est donc pas vraiment un problĂšme.

@DaleMckeown

Je publie via webdeploy sur IIS.

Il existe quelques options qui peuvent ĂȘtre utilisĂ©es pour que le dĂ©ploiement Ă  l'aide de webdeploy fonctionne correctement (il prend en charge le changement de nom des fichiers verrouillĂ©s et la suppression automatique de l'application hors ligne). Est-ce le cas par dĂ©faut @shirhatti ?

@ajeckmans

Nous travaillons actuellement Ă  ce problĂšme en supprimant d'abord le fichier web.config (en tuant effectivement l'application), mais ce n'est pas vraiment une solution acceptable Ă  long terme.

Cela signifie-t-il que vous effectuez un déploiement xcopy?

Il existe quelques options qui peuvent ĂȘtre utilisĂ©es pour que le dĂ©ploiement Ă  l'aide de webdeploy fonctionne correctement (il prend en charge le changement de nom des fichiers verrouillĂ©s et la suppression automatique de l'application hors ligne). Est-ce le cas par dĂ©faut @shirhatti ?

Merci David - sonne mieux que ce que je fais actuellement (arrĂȘt manuel du site et du pool d'applications dans IIS). Pouvez-vous indiquer quelques ressources pour que je puisse Ă©tudier les implications de ces approches?

@DaleMckeown quelques informations jusqu'à ce que je trouve la source de la vérité https://github.com/Microsoft/vsts-tasks/issues/5259#issuecomment -346202503

@davidfowl Nous utilisons webdeploy pour déployer sur notre serveur de tests (qui btw ne nous pose jamais de problÚmes), à partir de là, nous copions les fichiers sur nos serveurs en direct en utilisant robocopy

@ajeckmans

Nous travaillons actuellement Ă  ce problĂšme en supprimant d'abord le fichier web.config

Lorsque le fichier web.config est supprimĂ© du dĂ©ploiement, IIS servira les fichiers sensibles du dĂ©ploiement. Un attaquant pourrait simplement demander des fichiers en continu jour et nuit jusqu'Ă  ce que la fenĂȘtre de la trentaine s'ouvre.

@DaleMckeown

En suivant les conseils de https://github.com/guardrex/aspnetcore-iis-ps-publish ... mais regardez simplement cela comme un exemple expérimental et non comme un script de qualité de production. Je n'ai pas joué avec ça depuis un moment, mais ça devrait (en théorie) toujours fonctionner.

@guardrex vous avez raison. Nous copions d'abord un app_offline.htm dans le répertoire, puis nous remivons le web.config, copions sur l'application, remettons le web.config et supprimons l'app_offline (le tout avec un script ofc). Malheureusement, le simple fait de placer le fichier app_offline dans le répertoire des sites Web ne rompt pas le verrou sur les dll. Nous devons supprimer le web.config, une action que nous n'avons pas besoin de faire pour les anciennes applications complÚtes asp.net (comme les anciens formulaires Web, etc.)

@ajeckmans Cela ne devrait pas fonctionner. Lorsque le fichier web.config est supprimé, IIS sélectionne immédiatement ce changement, il doit donc demander par défaut au module de fichier statique et commencer à servir les fichiers. Essayez-le et voyez si c'est ce qui se passe ...

  1. Ajoutez app_offline.htm .
  2. Confirmez que le site sert app_offline.htm .
  3. Extrayez le fichier web.config .
  4. Demandez un fichier sensible (par exemple, http://localhost:<PORT>/<ASSEMBLY_NAME>.deps.json ... en remplaçant le PORT et le ASSEMBLY_NAME).
  5. Vous devriez obtenir le fichier deps.json servi si votre module de fichier statique fonctionne correctement.

Je ne ferais pas confiance Ă  la simple suppression du module avec ...

<configuration> 
 <system.webServer> 
   <modules> 
     <remove name="StaticFileModule" /> 
   </modules> 
 </system.webServer> 
</configuration>

... puisque d'autres modules resteraient et prĂ©senteraient Ă©ventuellement d'autres vecteurs d'attaque. On pourrait peut-ĂȘtre supprimer tous les modules non essentiels, mais nous entrons dans des eaux inexplorĂ©es avec un mouvement comme celui-lĂ  juste pour couvrir un dĂ©ploiement via la suppression de web.config . Cela n'a jamais Ă©tĂ© une option sous la direction officielle, et elle n'est donc pas du tout prise en charge. Je recommande le script PS, par exemple, pour supprimer AppPool, ou une autre stratĂ©gie.

Je suppose que je devrais ajouter une note de sympathie à cela ... cela a soulevé quelques sourcils du point de vue de la sécurité. Lorsque ce changement de disposition de déploiement a été effectué, il a été discuté, y compris la remise du fichier dans wwwroot , voir ...

Discussion pour: Publier pour les modifications IIS Ă  l'emplacement web.config (IISIntegration 158)
Head-check sur le déplacement de web.config vers wwwroot (IISIntegration 164)

[EDIT] C'est peut-ĂȘtre votre solution de contournement (non prise en charge): dĂ©placez le web.config vers wwwroot , puis continuez ce que vous faites. Encore ... un peu effrayant de casser l'application pour la mettre hors ligne comme ça.

Cela me laisse encore plus confus sur ce que nous devrions faire dans cette situation.

Quelle est la recommandation actuelle pour la publication de sites AspNetCore sur IIS via un déploiement Web de maniÚre à éviter les verrouillages de fichiers?

J'aimerais aussi savoir. Cela devient un obstacle majeur Ă  l'adoption du noyau .net dans mon organisation.

Lorsque mon application Web principale .net est en cours d'exĂ©cution et que j'essaie de publier une nouvelle version, cela me donne une erreur indiquant que les DLL sont en cours d'utilisation. Je dois donc arrĂȘter le pool d'applications, puis mettre Ă  jour les DLL et dĂ©marrer le pool d'applications.

Existe-t-il une solution de contournement dans .Net Core par laquelle je peux publier la nouvelle version / DLL sans arrĂȘter le pool d'applications?

Ceci est pris en charge par dĂ©faut dans le framework .Net Ă  l'aide du mĂ©canisme de clichĂ© instantanĂ©. Malheureusement, cela fait 2 ans depuis le lancement de .Net core et il semble qu'il n'y ait toujours pas de support pour ces fonctionnalitĂ©s trĂšs basiques et requises. Y a-t-il mĂȘme des plans pour rĂ©soudre ce problĂšme Ă  l'avenir?

Merci d'avance pour votre aide.

@guardrex, il est en effet effrayant de casser l'application pour que IIS (ou tout ce qui retient le verrou) libÚre les dll, mais il est encore plus effrayant de ne pas pouvoir pousser les correctifs sur un produit. Pour le moment, casser l'application est la seule chose que nous pouvons faire, mais nous examinons souvent d'autres approches plus modernes pour gérer cela :)

@ shahjay748 ne
Lequel ofc ne nous aide pas qui sont, pour le moment, coincés avec d'anciens processus :)

Ce que je fais (je ne sais pas si c'est une bonne façon de le faire), c'est télécharger le site dans un autre répertoire et changer de chemin dans iis

Nous avons menĂ© une enquĂȘte interne sur ce problĂšme. D'aprĂšs ce que je peux dire, ANCM ne contient aucun fichier / descripteur dans l'application dĂ©ployĂ©e. Cela semble ĂȘtre un problĂšme avec webdeploy lui-mĂȘme, et le dĂ©ploiement Ă©choue de maniĂšre saccadĂ©e. Je n'ai jamais fait Ă©chouer systĂ©matiquement le dĂ©ploiement de l'application aprĂšs avoir rĂ©essayĂ© plusieurs fois une fois que app_offline a Ă©tĂ© supprimĂ©.

Ajout d'une note d'accompagnement PowerShell rapide à cela: le verrou sur l'assembly de l'application est toujours libéré ... Je n'ai jamais eu de problÚme ( encore! Lol).

@ bpetersen1 ... Votre approche de "mise en scĂšne" a le doux effet secondaire d'offrir une option de restauration rapide si le nouveau dĂ©ploiement Ă©choue. Cela devrait ĂȘtre facile Ă  Ă©crire si nĂ©cessaire.

C'est toujours ennuyeux à l'extérieur ... nous avons décidé de chercher une solution de docker afin de laisser IIS derriÚre.

Je vais expérimenter une solution. Restez à l'écoute.

J'ai Ă©galement ce problĂšme en utilisant FTP.

Quel est le conseil de Microsoft Ă  ce sujet?!

J'ai Ă©galement ce problĂšme en utilisant FTP.

Quel est le conseil de Microsoft Ă  ce sujet?!

DĂ©posez un fichier appoffline.htm, puis ftp puis supprimez-le.

@davidfowl Oui, c'est ce que je fais en ce moment avec un fichier batch. Il faut quelques secondes à IIS pour libérer le verrou, puis copier les fichiers.

Merci - par intĂ©rĂȘt comment exĂ©cutez-vous le fichier batch?

Aussi un lien vers la documentation de MIcrosoft sur ce sujet apprécié; Je ne le trouve pas sur google. Merci.

@ niico100 Fondamentalement, le fichier de commandes copie simplement les fichiers dans le répertoire du projet, et je crée un dossier de sauvegarde avant de le faire. Avant de copier les fichiers, placez appoffline.htm dans le dossier du projet.
Cause le problĂšme de verrouillage de fichier, la copie effectuera une nouvelle tentative. J'utilise robcopy
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy

Si quelqu'un est intĂ©ressĂ©, le script suivant tĂ©lĂ©charge le fichier de dĂ©ploiement depuis appveyor, arrĂȘte le site, copie les fichiers requis et rĂ©tablit le site:
https://github.com/IsraelHikingMap/Site/blob/master/Scripts/Deploy.ps1
Il nĂ©cessite cependant d'ĂȘtre exĂ©cutĂ© en tant qu'administrateur. j'espĂšre que docker rĂ©soudra tout ce non-sens une fois que nous aurons migrĂ© ...
il utilise les commandes Stop-WebAppPool et Start-WebAppPool powershell.

Pour le développement local, WebDeploy n'a pas fonctionné pour moi. J'ai essayé de l'utiliser contre mon IIS local et il se plaignait toujours de fichiers verrouillés. J'ai ensuite essayé d'utiliser les commandlets PowerShell ci-dessus à partir d'événements VS Pre / Post build, mais cela n'a pas fonctionné pour moi non plus, probablement parce que PowerShell 32 bits ne peut pas modifier les paramÚtres IIS 64 bits? Quoi qu'il en soit, ce qui semble bien fonctionner, ce sont les événements pré / post build suivants dans mon projet ASP.Net Core:

ÉvĂ©nement de prĂ©-construction:
echo "App Offline" /a > $(ProjectDir)app_offline.htm

ÉvĂ©nement post-construction:
del $(ProjectDir)app_offline.htm

J'ai parcouru briĂšvement les plaintes ici, et il semble que cela puisse ĂȘtre liĂ©. J'ai dĂ©placĂ© les dĂ©ploiements CI pour nous du dĂ©ploiement d'octopus qui gĂ©nĂ©ralement "juste fonctionnĂ©", Ă  l'utilisation des versions azure devops avec les tĂąches de gestion iis, et j'ai encore assez souvent des problĂšmes pour dĂ©ployer de nouveaux fichiers car mĂȘme aprĂšs l'arrĂȘt de l'application web, l'arrĂȘt du domaine d'application, les fichiers sont toujours en cours utilisation.

Il s'agit probablement d'au moins 1 déploiement sur 3 et je n'ai rien trouvé qui semble améliorer la situation ou qui se déploie plus fiable.

@Tratcher @ronnyek Cela semble ĂȘtre liĂ© Ă  Application Insights; aprĂšs avoir ajoutĂ© l'extension App Insights, ma DLL d'application Web est soudainement trĂšs difficile Ă  mettre Ă  jour, aucun problĂšme avant.

Cela aurait du sens étant donné qu'App Insights doit connecter le profileur au processus d'application et aux DLL.

Je suis toujours confronté à ce problÚme. J'utilise le drapeau -e nableRule: AppOffline , parfois cela fonctionne bien mais la plupart du temps, le déploiement échoue en saing "ERROR_FILE_IN_USE".

AprÚs avoir démarré une version, je surveille le dossier de l'application Web et vois le App_Offline.html déposé par msdeploy. Ensuite, la version a échoué avec le message ci-dessus et notez le fichier App_Offline toujours dans le dossier, je relance la version, cette fois cela fonctionne bien car le module voit le fichier dans le dossier.

dernier runtime asp.net core installé -> aspnetcore.dll 12.1.18263.2

Des idées ? Encore un bug?

@dhtek Si vous essayez de remplacer les fichiers immĂ©diatement aprĂšs avoir placĂ© le app_offline.htm , alors le serveur n'a tout simplement pas eu le temps d'arrĂȘter l'application. Vous devriez attendre un peu avant d'essayer de remplacer les fichiers.

Ok, je comprends mais j'utilise l' option -e

Je vois toujours ce problÚme aussi. Mes fichiers de projet font référence à Microsoft.NET.Sdk.Web , mais il ne supprime pas automatiquement un fichier app_offline.htm , comme indiqué dans la documentation.

Salut les gars. Ce problĂšme ennuyeux est toujours prĂ©sent avec Core 2.1 avec le dernier VS 2017. J'utilise appoffline, toujours la DLL du projet principal est toujours utilisĂ©e et nĂ©cessite un arrĂȘt complet du site Web lors de la publication. Cela rend le dĂ©ploiement Web presque inutile.

Si vous ne pouvez pas mettre votre hĂŽte hors ligne derriĂšre l'Ă©quilibreur de charge et que vous souhaitez le faire plus rapidement, voici un moyen avec des liens symboliques et des PowerShell.
Je pensais faire quelque chose comme ça.

C'est plus rapide, car vous n'avez pas Ă  arrĂȘter le pool d'applications pendant la copie + recyclage, c'est mieux qu'un arrĂȘt brutal car cela permet aux demandes actuelles de se terminer, donc moins de temps d'arrĂȘt.

# Setup
Import-Module WebAdministration
# create 2 site root directories
$a = 'C:\inetpub\AspNetCoreSampleA'
$b = 'C:\inetpub\AspNetCoreSampleB'
$siteRoot = 'C:\inetpub\aspnetcoresample'
$siteName = 'AspNetCoreSample'
$poolName = "aspnetcore"
New-Item -Type Directory $a
New-Item -Type Directory $b
# create a symlink to targeting one side
New-Item -Type SymbolicLink -Path $siteRoot -Target $a
# point the site root to the symlink
Set-ItemProperty "IIS:\Sites\$siteName" -name physicalPath -value $siteRoot
# make sure it get's picked up
Restart-WebAppPool -Name $poolName

# this tells you the active side
Get-Item -Path $siteRoot | Select-Object -ExpandProperty target

# Flip the symlink
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
# at this point w3wp.exe still locks the current target folder until it's getting recycled
# Deploy new version to the symlink which is now pointing to the other side which should have no locks
robocopy \\myshare\myapp $siteRoot /mir
# recycle app pool, so it picks up the new files
Restart-WebAppPool -Name $poolName

# bonus point: rollback is easy
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
Restart-WebAppPool -Name $poolName

Voici l'essentiel
https://gist.github.com/csharmath/b2af0f50700ce9fbdd8c5c3e582fd41b

Restart-WebAppPool est essentiellement un recyclage, ce qui est utile si le recyclage avec chevauchement est activé (par défaut) car il engendrera un nouveau w3wp.exe et toutes les nouvelles demandes seront servies par ce nouveau processus pendant que celles en cours d'exécution seront terminées par l'ancien w3wp.exe.
De cette façon, ils se chevauchent jusqu'à ce que l'ancien soit terminé avec les demandes, vous vous retrouvez avec un seul w3wp.exe pointant vers la nouvelle version et il n'y a pas de problÚme de verrouillage.

C'est un peu similaire à la copie d'ombre, mais pas à 100% car cela fournit un scénario de xcopy beaucoup plus agréable et transparent.

Jusqu'Ă  prĂ©sent, cela semble ĂȘtre la meilleure approche Ă  laquelle je puisse penser si vous deviez rester en ligne pendant une sortie.

@csharmath ou il y a aussi docker je suppose. Aucun verrouillage de fichier de cette façon, et il peut faire des mises à jour progressives via swarm / k8s / okd

Bien sûr, c'est encore mieux, bien sûr. soupir, tous les endroits ne l'ont pas encore.
Pour le reste des configurations oldschool, vous devez le raser jusqu'Ă  ce qu'il fonctionne pour vous avec un temps d'arrĂȘt nul ou minimal.

@csharmath D'accord, mais à ce stade, étant donné qu'il s'agit d'un problÚme non résolu depuis _ans_, autant s'adapter et rechercher des solutions qui fonctionnent au lieu d'attendre un miracle ...

J'ai utilisĂ© ci-dessous le script power shell et il a plantĂ© l'IIS et a mĂȘme affectĂ© l'autre pool d'applications et je dois redĂ©marrer la machine pour tout rĂ©cupĂ©rer ... ce processus je l'ai obtenu Ă  partir du document officiel et c'Ă©tait un dĂ©sastre, donc mon conseil est de NE PAS UTILISER LE app_offline.htm mieux utiliser le script qui arrĂȘte le pool d'applications et le redĂ©marrer, celui que j'ai trouvĂ© dans ce fil https://github.com/IsraelHikingMap/Site/blob/master/Scripts/Deploy .ps1

$pathToApp = 'G:\prod_web_core'
$pathToAppOfflineHtml = 'G:\prod_web_core\app_offline.htm'
# Stop the AppPool 
New-Item -Path $pathToApp -Name app_offline.htm
# Provide script commands here to deploy the app
Copy-Item "G:\prod_web_core_temp\*" -Destination $pathToApp -Recurse -Force
# Restart the AppPool 
Remove-Item -Path $pathToAppOfflineHtml
Get-ChildItem -Path "G:\prod_web_core_temp" -Recurse | Remove-Item -Force

Je suis obligĂ© d'arrĂȘter AppPool pour rĂ©ussir le dĂ©ploiement, des progrĂšs pour rĂ©soudre ce problĂšme?!

Nous venons de rencontrer ce problĂšme de verrouillage de fichier pour la premiĂšre fois aujourd'hui, car dotnet core est nouveau pour nous. J'ai Ă©tĂ© vraiment pris au dĂ©pourvu par cela. C'est drĂŽle que la premiĂšre raison pour laquelle je suis passĂ© d'ASP classique Ă  .Net Framework alors qu'il Ă©tait encore en version bĂȘta (~ 2001) soit parce que je pouvais faire des dĂ©ploiements Ă  chaud sans verrouillage de fichiers. C'Ă©tait gĂ©nial! Presque 18 ans plus tard et maintenant je suis de retour lĂ  oĂč j'ai commencĂ©. Oh bien, vous gagnez certains, vous perdez un peu.

Je viens de faire référence à mon problÚme ... dans mon cas, le déploiement de solutions Blazor Server Side ...
Il y a quelques jours, c'Ă©tait un cauchemar ... J'ai appliquĂ© l'app_offline.htm, fermĂ© les pools d'applications et mĂȘme redĂ©marrĂ© des instances IIS entiĂšres pour dĂ©verrouiller des fichiers. La prochaine Ă©tape aurait Ă©tĂ© de redĂ©marrer tout le serveur, heureusement aprĂšs 5 minutes, les .dll se sont dĂ©verrouillĂ©s.

2019, mĂȘme problĂšme pour moi ... et ce problĂšme a Ă©tĂ© crĂ©Ă© en 2016 ... toujours pas de solution?

2020, mĂȘme problĂšme pour moi. La plus grande rĂ©gression jamais rĂ©alisĂ©e. .Net 4.6 vous remplacez les fichiers dll et l'application se recharge sur la nouvelle version. Le noyau .Net verrouille tout.

@bladefist Votre meilleur pari Ă  ce jour est d'utiliser des conteneurs Docker: /

@kanadaj merci, mais Dockers est un autre niveau de maux de tĂȘte Ă  gĂ©rer. J'ai finalement trouvĂ© un travail autour duquel utiliser App_offline.htm, puis attendre une minute et espĂ©rer que les fichiers sont libres. 99% du temps qu'ils le sont, il vous suffit d'attendre, je suppose que mon application met un certain temps Ă  s'Ă©teindre.

Fini le temps de .net 4.6 oĂč vous venez de copier vos dll et votre application est automatiquement recyclĂ©e. Je suppose que c'Ă©tait trop simple. Ce qui est doublement frustrant, c'est que ce n'est pas un problĂšme sous Linux. Vous pouvez remplacer les fichiers utilisĂ©s sous linux.

Eh bien oui je suppose, mais cette mĂ©thode n'est pas trĂšs simple dans un environnement de production. Sans HA, votre application finira par ne pas rĂ©pondre pendant une minute, et avec HA, vous recevrez des demandes erronĂ©es alĂ©atoires jusqu'Ă  ce que l'Ă©quilibreur de charge comprenne que l'application est en panne ... À moins que vous ne cycliez manuellement les hĂŽtes de votre Ă©quilibreur de charge. Mais cela semble encore plus difficile Ă  mettre en place.

@kanadaj oui , nous utilisons un Ă©quilibreur de charge et il met Ă  jour linĂ©airement les serveurs. Pas de temps d'arrĂȘt.

Nous avons eu du succĂšs avec

  • Utilisation d'un lien symbolique pour le rĂ©pertoire de l'application
  • DĂ©ployer une nouvelle version du site dans un autre rĂ©pertoire
  • Mettre Ă  jour le lien symbolique
  • RedĂ©marrez le pool d'applications Ă  l'aide de l'utilitaire appcmd fourni avec IIS.

@davidglassborow c'est une solution crĂ©ative. Merci. Cependant, des solutions crĂ©atives ne devraient pas ĂȘtre nĂ©cessaires.

D'aprÚs mon expérience, l'ancien mécanisme n'était de toute façon pas fiable lorsque le site était sous charge, nous avons fini par mettre de toute façon des proxys inverses pour les sites à fort trafic.

Bon, les déploiements sur place n'étaient jamais fiables ou atomiques, si vous aviez de la chance ou que vous n'aviez pas beaucoup de trafic, ce serait bien. Je suppose que la majorité des plaintes concernent ces scénarios. Nous examinerons l'amélioration des choses dans le délai .NET 5.0. Quelques mises en garde:

  • Nous chercherons Ă  amĂ©liorer les choses pour les applications dĂ©pendant du framework. Si vous dĂ©ployez autonome, vous n'avez pas de chance. Il verrouille les fichiers natifs et gĂ©rĂ©s dans le dossier de sortie. Le problĂšme de verrouillage des DLL natives a toujours existĂ© et ne sera pas rĂ©solu par les mesures d'attĂ©nuation que nous mettons en place.
  • Nous prĂ©voyons d'examiner le chargement des assemblys d'applications en mĂ©moire sous forme d'octets au lieu de les charger Ă  partir du disque et de verrouiller le fichier. Cela devrait convenir dans la plupart des cas, mais peut entraĂźner une utilisation plus importante de la mĂ©moire dans certains cas.
  • Afin de recycler l'application, vous devez toujours ajouter et supprimer un fichier appoffline. L'ajout du fichier appoffline est un moyen de signaler que vous souhaitez que l'application redĂ©marre Ă  la suite du dĂ©ploiement.

@davidfowl Le plan que vous avez décrit pour la version 5.0 sonne bien. Nous utilisons le framework dépendant comme je suis sûr que la plupart le font.

Respectueusement en dĂ©saccord sur la fiabilitĂ© des dĂ©ploiements en place. Je le fais depuis des annĂ©es sur des sites avec une charge extrĂȘmement Ă©levĂ©e, je n'ai jamais eu de problĂšme, pas une seule fois. Le premier changement dĂ©tectĂ© provoque la rĂ©initialisation de l'application, l'Ă©quilibreur de charge voit que l'instance ne rĂ©pond pas, la met hors ligne, une fois que toutes les DLL sont remplacĂ©es, l'Ă©quilibreur de charge effectue une vĂ©rification de l'Ă©tat et il revient en ligne. Maintenant, s'il n'y avait pas de vĂ©rification de l'Ă©tat de l'Ă©quilibreur de charge, alors oui, c'est un pari, mais je veux dire qui remplace les DLL en production sous une charge Ă©levĂ©e sans proxy quelconque? Concentrons-nous sur la rĂšgle et non sur l'exception. Sans proxy, je ne vois aucun moyen de mettre Ă  jour l'application sans provoquer de panne. MĂȘme si vous preniez en charge le rechargement Ă  chaud, certaines demandes se bloqueraient ou Ă©choueraient probablement.

Respectueusement en dĂ©saccord sur la fiabilitĂ© des dĂ©ploiements en place. Je le fais depuis des annĂ©es sur des sites avec une charge extrĂȘmement Ă©levĂ©e, je n'ai jamais eu de problĂšme, pas une seule fois. Le premier changement dĂ©tectĂ© provoque la rĂ©initialisation de l'application, l'Ă©quilibreur de charge voit que l'instance ne rĂ©pond pas, la met hors ligne, une fois que toutes les DLL sont remplacĂ©es, l'Ă©quilibreur de charge effectue une vĂ©rification de l'Ă©tat et il revient en ligne. Maintenant, s'il n'y avait pas de vĂ©rification de l'Ă©tat de l'Ă©quilibreur de charge, alors oui, c'est un pari, mais je veux dire qui remplace les DLL en production sous une charge Ă©levĂ©e sans proxy quelconque? Concentrons-nous sur la rĂšgle et non sur l'exception. Sans proxy, je ne vois aucun moyen de mettre Ă  jour l'application sans provoquer de panne. MĂȘme si vous preniez en charge le rechargement Ă  chaud, certaines demandes se bloqueraient ou Ă©choueraient probablement.

Vous disposez d'un Ă©quilibreur de charge. Beaucoup de gens n'ont pas d'Ă©quilibreur de charge et ne font que remplacer les fichiers sur le disque en place et s'attendent Ă  la magie 😄

@davidfowl Droit mais trafic élevé + pas de lb = imprudent

De plus, le problĂšme avec app_offline.htm est qu'Ă  partir d'un processus ci / cd, vous ne savez pas quand le processus s'arrĂȘte. Nous avons dĂ» ajouter une Ă©norme commande de mise en veille entre la crĂ©ation de ce fichier et l'envoi des DLL, car notre processus d'arrĂȘt peut durer de 1 Ă  1 minute. Lorsque vous Ă©quilibrez la charge de tonnes d'instances, ces mises en veille s'additionnent Ă  un cycle de dĂ©ploiement trĂšs long.

Le chargement des fichiers en mémoire résout tout cela.

@davidfowl Droit mais trafic élevé + pas de lb = imprudent

👍

De plus, le problĂšme avec app_offline.htm est qu'Ă  partir d'un processus ci / cd, vous ne savez pas quand le processus s'arrĂȘte. Nous avons dĂ» ajouter une Ă©norme commande de mise en veille entre la crĂ©ation de ce fichier et l'envoi des DLL, car notre processus d'arrĂȘt peut durer de 1 Ă  1 minute. Lorsque vous Ă©quilibrez la charge de tonnes d'instances, ces mises en veille s'additionnent Ă  un cycle de dĂ©ploiement trĂšs long.

Bon, le problÚme est que la suppression de ce fichier ne vous dit pas quand il est correct de démarrer le déploiement car les fichiers sont toujours verrouillés jusqu'à ce que la notification soit reçue par ANCM.

De plus, le problĂšme avec app_offline.htm est qu'Ă  partir d'un processus ci / cd, vous ne savez pas quand le processus s'arrĂȘte.

À droite, l'Ă©diteur VS utilise des mises en veille courtes et plusieurs tentatives.

  • Afin de recycler l'application, vous devez toujours ajouter et supprimer un fichier appoffline. L'ajout du fichier appoffline est un moyen de signaler que vous souhaitez que l'application redĂ©marre Ă  la suite du dĂ©ploiement.

Serait-il possible d'avoir un fichier "apprestart" pour marquer l'application Ă  recycler sans avoir Ă  supprimer le fichier appoffline par la suite?

@Socolin pourquoi est-ce?

@Socolin pourquoi est-ce?

Si je comprends bien (dites-moi si je me trompe), ce que vous prévoyez est de supprimer le verrou, mais nous devrons toujours créer appoffline pour signaler à IIS de recycler l'application une fois la compilation terminée?

Pour ce faire, nous devrons crĂ©er le fichier appoffline, puis le supprimer. Ce fichier peut-il ĂȘtre supprimĂ© immĂ©diatement aprĂšs sa crĂ©ation? ou devrions-nous attendre qu'IIS le dĂ©tecte? S'il faut attendre un peu, je prĂ©fĂ©rerais avoir un fichier comme "apprestart" qu'IIS Ă©coutera, puis supprimera une fois qu'il le dĂ©tectera et commencera Ă  recycler.


Aussi, j'ai une autre question en tĂȘte. Il s'agit de l'optimisation IDE lors de la construction.

Actuellement, je travaille sur un projet qui utilise des dépendances, nous avons un projet pour la couche Web et un autre projet pour la logique et les données. Lorsque je travaille dans la couche Web (ASP.NET Core) pendant la génération, je crée un fichier appoffline avant la génération, puis je le supprime aprÚs la génération et cela fonctionne.

Mais quand je travaille dans l'une des dĂ©pendances, quand je les construis Ă  partir de Rider (je pense que ça fait la mĂȘme chose sur VS car il utilise msbuild) quand je regarde ce que fait msbuild, une fois la construction du projet terminĂ©e, le dll est copiĂ© directement dans le rĂ©pertoire .Web / bin sans reconstruire le projet .Web. Et comme la DLL est verrouillĂ©e, elle Ă©choue silencieusement et je dois redĂ©marrer manuellement le serveur ou dĂ©clencher manuellement la construction du projet .Web.

Avez-vous une solution pour cela?
Jusqu'Ă  prĂ©sent, la solution de contournement que j'ai trouvĂ©e est d'Ă©crire un petit programme exĂ©cutĂ© en arriĂšre-plan qui recherche le / bin de mon projet .Web. Lorsqu'un fichier change, il crĂ©e un fichier appoffline dans le rĂ©pertoire oĂč IIS Ă©coute, puis copie les fichiers modifiĂ©s, puis supprime le fichier appoffline. Mais cela semble un peu piratĂ©, mais jusqu'Ă  prĂ©sent, c'est le seul moyen que j'ai trouvĂ© pour pouvoir construire, puis appuyez sur F5 et testez mes modifications.

Pour ce faire, nous devrons crĂ©er le fichier appoffline, puis le supprimer. Ce fichier peut-il ĂȘtre supprimĂ© immĂ©diatement aprĂšs sa crĂ©ation? ou devrions-nous attendre qu'IIS le dĂ©tecte? S'il faut attendre un peu, je prĂ©fĂ©rerais avoir un fichier comme "apprestart" qu'IIS Ă©coutera, puis supprimera une fois qu'il le dĂ©tectera et commencera Ă  recycler.

Comment IIS saurait-il que vous avez terminé de copier des fichiers? Comment éviter l'état déchiré? Vous devez essentiellement signaler le début et la fin d'une transaction. La création du fichier signale le début et la suppression signale la fin.

Avez-vous une solution pour cela?
Jusqu'Ă  prĂ©sent, la solution de contournement que j'ai trouvĂ©e est d'Ă©crire un petit programme exĂ©cutĂ© en arriĂšre-plan qui recherche le / bin de mon projet .Web. Lorsqu'un fichier change, il crĂ©e un fichier appoffline dans le rĂ©pertoire oĂč IIS Ă©coute, puis copie les fichiers modifiĂ©s, puis supprime le fichier appoffline. Mais cela semble un peu piratĂ©, mais jusqu'Ă  prĂ©sent, c'est le seul moyen que j'ai trouvĂ© pour pouvoir construire, puis appuyez sur F5 et testez mes modifications.

VS gÚre cela en tuant le processus avant de démarrer un nouveau fichier pour tout ce qui pourrait avoir un impact sur la construction de ce projet.

Pour ce faire, nous devrons crĂ©er le fichier appoffline, puis le supprimer. Ce fichier peut-il ĂȘtre supprimĂ© immĂ©diatement aprĂšs sa crĂ©ation? ou devrions-nous attendre qu'IIS le dĂ©tecte? S'il faut attendre un peu, je prĂ©fĂ©rerais avoir un fichier comme "apprestart" qu'IIS Ă©coutera, puis supprimera une fois qu'il le dĂ©tectera et commencera Ă  recycler.

Comment IIS saurait-il que vous avez terminé de copier des fichiers? Comment éviter l'état déchiré? Vous devez essentiellement signaler le début et la fin d'une transaction. La création du fichier signale le début et la suppression signale la fin.

S'il n'y a pas de verrou, pourquoi notifier IIS lorsque la construction dĂ©marre? Ne pouvons-nous pas simplement signaler que tous les fichiers sont mis Ă  jour et que l'application doit ĂȘtre recyclĂ©e? Je pense que j'ai mal compris quelque chose.

S'il n'y a pas de verrou, pourquoi notifier IIS lorsque la construction dĂ©marre? Ne pouvons-nous pas simplement signaler que tous les fichiers sont mis Ă  jour et que l'application doit ĂȘtre recyclĂ©e? Je pense que j'ai mal compris quelque chose.

Oui, cela fonctionnerait. Je pensais que vous dĂ©criviez l'Ă©tat actuel de la technique. Il pourrait mĂȘme ĂȘtre possible de le faire aujourd'hui avec web.config. Si vous touchez le fichier, l'application redĂ©marrera.

J'ai eu du succÚs avec le déploiement sur place (https://flukefan.github.io/ZipDeploy/), en:

  1. Renommer les fichiers d'assemblage (apparemment, vous pouvez renommer mĂȘme si vous ne pouvez pas supprimer / Ă©craser);
  2. Copiez dans les nouveaux assemblages;
  3. Appuyez sur la configuration Web pour redémarrer l'application;
  4. Supprimez les anciens assemblys renommés.

Pas d'Ă©quilibrage de charge; instance IIS unique; aucun changement IIS. YMMV.

@FlukeFan Comment Ă©viter les dĂ©ploiements dĂ©chirĂ©s ou n'est-ce pas un problĂšme pour vous? Par dĂ©chirĂ©, je veux dire qu'il existe une fenĂȘtre dans laquelle l'ancienne application charge un nouvel assemblage avant de redĂ©marrer l'application.

Je ne touche pas le web.config tant que tous les assemblys ne sont pas renommés / mis à jour. Je suppose qu'il y a une petite chance que quelque chose d'autre puisse provoquer le recyclage d'un pool d'applications pendant ce temps, mais ce n'est pas encore arrivé.

Je désactive généralement toutes les autres options de recyclage automatique et je désactive également le recyclage superposé dans les paramÚtres du pool d'applications IIS.

@FlukeFan n'est pas un recyclage mais si vous n'avez pas encore chargĂ© l'assembly qui a Ă©tĂ© remplacĂ©. Par exemple, disons que vous avez un assembly A.dll et B.dll. Disons que B est utilisĂ© lorsque vous accĂ©dez Ă  la page des paramĂštres, il est donc chargĂ©. Si vous ĂȘtes allĂ© Ă  la page des paramĂštres lorsque B.dll a Ă©tĂ© remplacĂ© par le nouveau, vous pourriez vous retrouver avec l'ancienne application en cours d'exĂ©cution avec un nouveau B.dll.

Je me demande si nous devrions créer un outil global dotnet pour aider à ce type de déploiement. L'outil pourrait essentiellement faire toutes les choses difficiles que les gens ont mentionnées sur ce fil.

Pensées?

@FlukeFan n'est pas un recyclage mais si vous n'avez pas encore chargĂ© l'assembly qui a Ă©tĂ© remplacĂ©. Par exemple, disons que vous avez un assembly A.dll et B.dll. Disons que B est utilisĂ© lorsque vous accĂ©dez Ă  la page des paramĂštres, il est donc chargĂ©. Si vous ĂȘtes allĂ© Ă  la page des paramĂštres lorsque B.dll a Ă©tĂ© remplacĂ© par le nouveau, vous pourriez vous retrouver avec l'ancienne application en cours d'exĂ©cution avec un nouveau B.dll.

Donc je ne gĂšre pas cette affaire pour le moment. https://github.com/FlukeFan/ZipDeploy/blob/master/ZipDeploy/ZipDeploy.cs#L55

Je suppose que je pourrais faire les choses dans un ordre diffĂ©rent, toucher d'abord web.config, attendre la fin de toutes les `` autres '' requĂȘtes, puis enfin faire le remplacement juste avant la fin de la derniĂšre requĂȘte (pendant qu'IIS met en file d'attente les nouvelles requĂȘtes pour le about-to- recycle app-pool), mais ce que j'ai fonctionne pour moi tout Ă  l'heure.

Ce n'est probablement pas actuellement assez robuste pour le scénario que vous décrivez (mais je n'ai rien fait d'extraordinaire avec le chargement d'assemblage dynamique autre qu'au démarrage).

Est-il prĂ©vu de revoir cette fonctionnalitĂ© et de la mettre sur la feuille de route? Il est trĂšs peu pratique / peu convivial d'exiger de tout le monde qui dĂ©ploie un site Web .Net Core de mettre en Ɠuvre manuellement une stratĂ©gie de crĂ©neau intermĂ©diaire s'il souhaite prendre en charge les dĂ©ploiements sans temps d'arrĂȘt.

Cette fonctionnalité rendrait la transition vers les sites Web .Net Core beaucoup plus fluide pour de nombreuses personnes et permettrait une adoption plus rapide des sites Web .Net Core.

Je n'ai jamais pensĂ© Ă  ça. Mais vous pouvez trĂšs bien avoir frappĂ© le clou sur la tĂȘte. Cela pourrait ĂȘtre une dĂ©cision commerciale nĂ©faste de forcer les gens Ă  utiliser des machines Ă  sous azur. Si cela Ă©tait possible dans le passĂ©, pourquoi a-t-il fallu si longtemps pour «rĂ©parer» maintenant? Ce n'est pas rompu d'un point de vue commercial ce que cela Ă  l'esprit. Peut-ĂȘtre que je suis un peu cynique. Mais j'ai lentement regardĂ© les fonctionnalitĂ©s azur qui Ă©taient auparavant gratuites et sont passĂ©es Ă  des niveaux plus chers.

Je me demande si nous devrions créer un outil global dotnet pour aider à ce type de déploiement. L'outil pourrait essentiellement faire toutes les choses difficiles que les gens ont mentionnées sur ce fil.

Pensées?

C'est pour fonctionner sur le serveur CI, disons? Comment pousserait-il les binaires / package vers le serveur de destination?

Je n'ai jamais pensĂ© Ă  ça. Mais vous pouvez trĂšs bien avoir frappĂ© le clou sur la tĂȘte. Cela pourrait ĂȘtre une dĂ©cision commerciale nĂ©faste de forcer les gens Ă  utiliser des machines Ă  sous azur. Si cela Ă©tait possible dans le passĂ©, pourquoi a-t-il fallu si longtemps pour «rĂ©parer» maintenant? Ce n'est pas rompu d'un point de vue commercial ce que cela Ă  l'esprit. Peut-ĂȘtre que je suis un peu cynique. Mais j'ai lentement regardĂ© les fonctionnalitĂ©s azur qui Ă©taient auparavant gratuites et sont passĂ©es Ă  des niveaux plus chers.

Les dĂ©ploiements en place sans coordination sont fondamentalement peu fiables pour les raisons mentionnĂ©es ci-dessus. Nous n'allons plus jamais implĂ©menter le clichĂ© instantanĂ©, car cette fonctionnalitĂ© n'a pas toujours Ă©tĂ© fiable et a causĂ© de nombreux problĂšmes dans ASP.NET sur .NET Framework. Il ne fonctionne Ă©galement que pour un type de dĂ©ploiement spĂ©cifique, dĂ©pendant du framework, qui est entiĂšrement pris en charge par .NET Framework. .NET core prend en charge un fichier autonome et unique, ce qui le rend beaucoup plus difficile Ă  prendre en charge. MĂȘme la suggestion ci-dessus ne couvre pas ces cas.

Nous pensons toujours que les dĂ©ploiements sur place devraient ĂȘtre aussi atomiques que possible et que de nombreux problĂšmes sur ce problĂšme proviennent de bogues et du manque de fiabilitĂ© de la dĂ©tection et du recyclage app_offline, nous avons donc passĂ© beaucoup de temps Ă  rĂ©soudre ce problĂšme (et le verrouillage pdb Ă©galement).

Le dĂ©ploiement Web est le seul outil aujourd'hui qui incarne le flux avec lequel nous pensons qu'il est logique de dĂ©ployer, mais il est piĂ©gĂ© dans cette technologie, donc cela n'aide pas si vous dĂ©ployez ftp sur vos serveurs ou copiez sur un partage de fichiers (mĂȘme si pourrait).

Un outil global dotnet pourrait ĂȘtre une rĂ©ponse ici.

C'est pour fonctionner sur le serveur CI, disons? Comment pousserait-il les binaires / package vers le serveur de destination?

Je ne pense pas. Il prendrait probablement en charge FTP et une copie directe. Tout autre chose que cela est probablement un protocole propriétaire.

J'espÚre que quand vous dites FTP, vous voulez dire aussi ftp sur ssh. Un tel outil serait trÚs précieux.

J'espÚre que quand vous dites FTP, vous voulez dire aussi ftp sur ssh. Un tel outil serait trÚs précieux.

Non, je voulais dire ftp. Mais nous ferions tout ce qui aurait du sens. Il est peut-ĂȘtre prĂ©fĂ©rable d'ĂȘtre un outil de copie que vous devez exĂ©cuter sur la machine cible. Cela nous Ă©vite de devoir envoyer des bits n'importe oĂč.

Êtes-vous Ă©galement en SSH sur vos machines Windows pour le dĂ©ployer sur IIS?

@davidfowl Veuillez ajouter (opt-in) la prise en charge des emplacements de déploiement.
https://github.com/dotnet/aspnetcore/issues/3719#issuecomment -473183712
https://github.com/dotnet/aspnetcore/issues/3793#issuecomment -335666414

Nous prévoyons d'examiner le chargement des assemblys d'applications en mémoire sous forme d'octets au lieu de les charger à partir du disque et de verrouiller le fichier. Cela devrait convenir dans la plupart des cas, mais peut entraßner une utilisation plus importante de la mémoire dans certains cas .

De plus, cela ne nous permettra pas d'atteindre aucun temps d'arrĂȘt.

Il n'y a aucun moyen d'investir dans une telle fonctionnalité avec le module.

J'espÚre que quand vous dites FTP, vous voulez dire aussi ftp sur ssh. Un tel outil serait trÚs précieux.

Non, je voulais dire ftp. Mais nous ferions tout ce qui aurait du sens. Il est peut-ĂȘtre prĂ©fĂ©rable d'ĂȘtre un outil de copie que vous devez exĂ©cuter sur la machine cible. Cela nous Ă©vite de devoir envoyer des bits n'importe oĂč.

Êtes-vous Ă©galement en SSH sur vos machines Windows pour le dĂ©ployer sur IIS?

Oui. Nous utilisons CI / CD et dĂ©ployons Ă  la fois sur les systĂšmes Linux et Windows, il Ă©tait donc beaucoup plus facile d'installer openssh sur les fenĂȘtres.

$ appPool = 'par défaut'
Stop-WebAppPool -Nom $ appPool -Passthru
... déployer...

Start-WebAppPool -Nom $ appPool -Passthru
...déployer.....

ou

$ appPool = 'par défaut'
Stop-WebAppPool -Name $ appPool
while ((Get-WebAppPoolState -Name $ appPool) .Value -ne 'Stop') {
dormir 1 # seconde
}
... déployer...

Start-WebAppPool -Name $ appPool
while ((Get-WebAppPoolState -Name $ appPool) .Value -ne 'Start') {
dormir 1 # seconde
}

...déployer.....

Emplacements de déploiement des pauvres hommes
Il y a environ un an, j'ai publié un article sur la création de 2 dossiers racine de site et j'ai un point de lien symbolique vers l'un d'eux configuré pour le site IIS.
L'avantage est que votre temps d'arrĂȘt est moins comparĂ© aux autres solutions plus simples.
Si le recyclage avec chevauchement est activĂ©, aucun temps d'arrĂȘt, seulement une pĂ©nalitĂ© de prĂ©chauffage pour la premiĂšre demande, ce qui est le cas de toute façon.

Si l'opĂ©ration de dĂ©ploiement / copie prend N secondes pour se terminer, vous n'avez pas besoin d'arrĂȘter le pool d'applications pendant N secondes.
Pas de problĂšme avec l'application douteuse hors ligne.
Copiez simplement dans le dossier inactif, Ă©changez le lien symbolique lorsque les fichiers sont lĂ , puis recyclez le pool d'applications.
DĂ©ploiement atomique, pas de temps d'arrĂȘt juste une premiĂšre requĂȘte plus lente que d'habitude.

https://github.com/dotnet/aspnetcore/issues/3793#issuecomment -459870870

Quelqu'un a-t-il essayé ça?
Si quelque chose comme cela fonctionne, cela pourrait ĂȘtre transformĂ© en service avec un outil de dĂ©ploiement cĂŽtĂ© client.

  • client -> serveur quel est le dossier / partage inactif?
  • S: ici
  • C: ok dĂ©ployĂ© / copiĂ©
  • S: lien symbolique Ă©changĂ© et recyclĂ©
  • C: thx, http get / healthcheck (facultatif)
  • C: ugh j'ai foirĂ©, pls de retour en arriĂšre
  • S: Ă©change de lien symbolique, recyclage (retour aux affaires)
  • C: rincer rĂ©pĂ©ter jusqu'Ă  ce que fonctionne

J'ai donc Ă©galement des problĂšmes avec les fichiers verrouillĂ©s de dĂ©ploiement. dans l'hĂ©bergement d'applications. J'ai essayĂ© d'arrĂȘter le pool d'applications, mais les fichiers restent verrouillĂ©s. J'ai essayĂ© de pousser le app_offline.htm mais pas de chance non plus.
De plus, si vous souhaitez gérer la suppression du fichier app_offline.htm, vous pouvez facilement le faire en démarrant l'application dans program.cs. De cette façon, nous savons quand il démarre, il devient en ligne.

Le problĂšme actuel auquel je suis confrontĂ© est que les dll sont bloquĂ©es et mĂȘme si vous renommez puis copiez les fichiers, l'ancien processus est toujours en cours d'exĂ©cution sur les fichiers renommĂ©s. Ainsi, lorsque nous tenterons de dĂ©ployer Ă  nouveau, nous devrons renommer Ă  nouveau les fichiers. Je suppose que nous pourrions utiliser une date quelconque comme remplacement du nom de fichier.
Nous utilisons dotnet core 3.1.4 pour cela sur le serveur IIS Windows 2012 R2

@foxjazz Comment les fichiers sont-ils toujours verrouillĂ©s si le pool / processus d'applications est arrĂȘtĂ©? Peux-tu Ă©laborer?

@foxjazz Comment les fichiers sont-ils toujours verrouillĂ©s si le pool / processus d'applications est arrĂȘtĂ©? Peux-tu Ă©laborer?

image

image

Lorsque vous essayez de supprimer les DLL utilisées, l'image indique qu'elles sont utilisées par un autre processus.
Le pool d'applications est hors ligne depuis un certain temps.

VĂ©rifiez le gestionnaire de tĂąches pour voir si le processus est toujours en cours d'exĂ©cution. Appuyer sur le bouton d'arrĂȘt ne signifie pas qu'il se termine immĂ©diatement.

VĂ©rifiez le gestionnaire de tĂąches pour voir si le processus est toujours en cours d'exĂ©cution. Appuyer sur le bouton d'arrĂȘt ne signifie pas qu'il se termine immĂ©diatement.

l'image ci-dessus provient du gestionnaire de tĂąches. Je ne sais pas de quoi il s'agit, mais si je les supprime, le fichier sera libĂ©rĂ©. Je suppose que je peux utiliser handle pour dĂ©terminer le pid Ă  terminer. Je ne pensais pas que je devrais aller Ă  ces longueurs pour le dĂ©ploiement. Handle indique que les processus w3wp.exe 2 ont l'un des fichiers verrouillĂ©s. mĂȘme si le pool d'applications correspondant est arrĂȘtĂ©.

Ce qui serait vraiment bien, c'est d'avoir une route pour arrĂȘter le processus.
api \ KillDeathKill
{
Program.KillProcess ()
}

C'est peu probable. Le fichier est verrouillĂ© par un processus. Si w3wp est ce processus, il n'a jamais Ă©tĂ© tuĂ© au dĂ©part ou un nouveau a Ă©tĂ© lancĂ© avec un pid diffĂ©rent verrouillant le mĂȘme fichier. C'est pourquoi vous devez d'abord vous assurer que l'application hors ligne est arrĂȘtĂ©e pour vous assurer qu'il n'y a pas de nouveau processus pour verrouiller le fichier, tuer le processus existant, dĂ©ployer de nouveaux bits, supprimer l'application hors ligne

C'est peu probable. Le fichier est verrouillĂ© par un processus. Si w3wp est ce processus, il n'a jamais Ă©tĂ© tuĂ© au dĂ©part ou un nouveau a Ă©tĂ© lancĂ© avec un pid diffĂ©rent verrouillant le mĂȘme fichier. C'est pourquoi vous devez d'abord vous assurer que l'application hors ligne est arrĂȘtĂ©e pour vous assurer qu'il n'y a pas de nouveau processus pour verrouiller le fichier, tuer le processus existant, dĂ©ployer de nouveaux bits, supprimer l'application hors ligne

lorsque vous dites que app_offline.htm est en premier. Oui, c'Ă©tait le cas. J'ai un chemin de statut que je peux vĂ©rifier via une demande d'obtention, et il est dĂ©finitivement hors ligne. Également arrĂȘtĂ© le pool d'applications manuellement. Mais le processus w3wp bloquait toujours le fichier.

Ensuite, le processus n'a pas Ă©tĂ© arrĂȘtĂ©

Ensuite, le processus n'a pas Ă©tĂ© arrĂȘtĂ©

Alors, pourquoi est-ce que l'arrĂȘt du pool d'applications, et non le processus?

Le pool d'applications reprĂ©sente le processus et si vous arrĂȘtez le pool d'applications, le processus sera interrompu. Le fichier ne peut pas ĂȘtre verrouillĂ© s'il n'y a pas de processus pour le verrouiller, donc l'une de ces autres thĂ©ories semble plus probable.

Le pool d'applications reprĂ©sente le processus et si vous arrĂȘtez le pool d'applications, le processus sera interrompu. Le fichier ne peut pas ĂȘtre verrouillĂ© s'il n'y a pas de processus pour le verrouiller, donc l'une de ces autres thĂ©ories semble plus probable.

hah vous avez dit merde. Je ne veux pas avoir l'air de vous punir. Je dis que l'arrĂȘt du pool d'applications ne fonctionne PAS comme annoncĂ© dans toute la documentation. Le processus n'est pas interrompu, mĂȘme aprĂšs 90 secondes, il est toujours en cours d'exĂ©cution. Le fichier est verrouillĂ© mĂȘme lorsque vous pouvez voir clairement que le pool d'applications a Ă©tĂ© arrĂȘtĂ©. Le processus contient un singleton pour obtenir des donnĂ©es. Et d'autres contrĂŽleurs. Ce serait bien d'avoir un script qui arrĂȘterait le processus en fonction du fichier verrouillĂ©. Je pourrais alors me dĂ©ployer sans crainte. Le changement de nom peut Ă©galement fonctionner. Les fichiers peuvent ĂȘtre renommĂ©s. (dotnet core 3.1.4) saveur

Il y a environ un an, j'ai publié un article sur la création de 2 dossiers racine de site et j'ai un point de lien symbolique vers l'un d'eux configuré pour le site IIS.

Quelqu'un a-t-il essayé ça?
Si quelque chose comme cela fonctionne, cela pourrait ĂȘtre transformĂ© en service avec un outil de dĂ©ploiement cĂŽtĂ© client.

@CJHarmath - J'ai fait un essai et j'ai le code modifié que j'utilise ci-dessous. Fonctionne trÚs bien, merci!

Si je publiais davantage de mises à jour, je pourrais envisager un outil de déploiement client, mais en réalité, je peux simplement envoyer un shell distant dans le serveur IIS et exécuter le script PowerShell pour le retourner.
psexec.exe \\IIS_SERVER cmd /c "powershell -noninteractive -file C:\FlipSymLink.ps1"

# FlipSymLink.ps1

Import-Module WebAdministration # run as admin
# create 2 site root directories
$a = 'C:\Websites\MySiteA'
$b = 'C:\Websites\MySiteB'
$appRoot  = 'C:\Websites\MySite'
$appName  = 'MyAppName'
$siteName = 'MySiteName'
$poolName = "MyPoolName"
New-Item -Type Directory $a -ErrorAction SilentlyContinue
New-Item -Type Directory $b -ErrorAction SilentlyContinue

# create a symlink to targeting one side
New-Item -Type SymbolicLink -Path $appRoot -Target $a -Name A -ErrorAction SilentlyContinue
New-Item -Type SymbolicLink -Path $appRoot -Target $b -Name B -ErrorAction SilentlyContinue

# point the site root to the symlink
$currentPath = (Get-ItemProperty "IIS:\Sites\$siteName\$appName" -name physicalPath)
if ($currentPath -eq "$appRoot\A") {
    Write-Host "Switched to B"
    New-Item $b\active.txt
    Remove-Item $a\active.txt
    Set-ItemProperty "IIS:\Sites\$siteName\$appName" -name physicalPath -value $appRoot\B
} else {
    Write-Host "Switched to A"
    New-Item $a\active.txt
    Remove-Item $b\active.txt
    Set-ItemProperty "IIS:\Sites\$siteName\$appName" -name physicalPath -value $appRoot\A
}
Restart-WebAppPool -Name $poolName

psexec.exe \\IIS_SERVER cmd /c "powershell -noninteractive -file C:\FlipSymLink.ps1"

Cela pourrait Ă©galement ĂȘtre transformĂ© en un point de terminaison JEA , vous pouvez donc exĂ©cuter flip tant qu'utilisateur non Ă©levĂ© (par exemple Ă  partir d'une Ă©tape de dĂ©ploiement du serveur CI / CD)
Invoke-Command -ComputerName IIS_SERVER -ConfigurationName IIS-Flip -ScriptBlock { Switch-SymlinkTarget -SiteName MySite}
Utilisé Switch au lieu de Flip car c'est un verbe approuvé.

Utilisé Switch au lieu de Flip car c'est un verbe approuvé.

Swap est le verbe utilisé lorsqu'il s'agit de slots - serait-il logique de le réutiliser ici semble-t-il?

ayant le mĂȘme problĂšme que dĂ©crit il y a 4 ans.
Une mise Ă  jour pour ceci?
Je ne veux pas ouvrir le bureau à distance pour simplement télécharger un nouveau fichier dll.

Lorsque j'essaie de remplacer le fichier DLL d'application .NET Core Ă  l'aide de FTP sur le serveur de production IIS, le fichier est verrouillĂ© et ne peut pas ĂȘtre Ă©crasĂ©.

Pour dĂ©ployer une nouvelle version, je dois arrĂȘter l'application dans IIS (ouverture de RDP) pour dĂ©verrouiller, puis Ă©craser.
Il n'est pas possible de dĂ©ployer sans arrĂȘter l'application.

Une solution pour ça? Merci

Si vous ne pouvez pas mettre votre hĂŽte hors ligne derriĂšre l'Ă©quilibreur de charge et que vous souhaitez le faire plus rapidement, voici un moyen avec des liens symboliques et des PowerShell.
Je pensais faire quelque chose comme ça.

C'est plus rapide, car vous n'avez pas Ă  arrĂȘter le pool d'applications pendant la copie + recyclage, c'est mieux qu'un arrĂȘt brutal car cela permet aux demandes actuelles de se terminer, donc moins de temps d'arrĂȘt.

# Setup
Import-Module WebAdministration
# create 2 site root directories
$a = 'C:\inetpub\AspNetCoreSampleA'
$b = 'C:\inetpub\AspNetCoreSampleB'
$siteRoot = 'C:\inetpub\aspnetcoresample'
$siteName = 'AspNetCoreSample'
$poolName = "aspnetcore"
New-Item -Type Directory $a
New-Item -Type Directory $b
# create a symlink to targeting one side
New-Item -Type SymbolicLink -Path $siteRoot -Target $a
# point the site root to the symlink
Set-ItemProperty "IIS:\Sites\$siteName" -name physicalPath -value $siteRoot
# make sure it get's picked up
Restart-WebAppPool -Name $poolName

# this tells you the active side
Get-Item -Path $siteRoot | Select-Object -ExpandProperty target

# Flip the symlink
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
# at this point w3wp.exe still locks the current target folder until it's getting recycled
# Deploy new version to the symlink which is now pointing to the other side which should have no locks
robocopy \\myshare\myapp $siteRoot /mir
# recycle app pool, so it picks up the new files
Restart-WebAppPool -Name $poolName

# bonus point: rollback is easy
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
Restart-WebAppPool -Name $poolName

Voici l'essentiel
https://gist.github.com/csharmath/b2af0f50700ce9fbdd8c5c3e582fd41b

Voici quelque chose dont je pense avoir rĂ©glĂ© les problĂšmes. Je n'ai essayĂ© qu'avec ASP.NET, mais j'imagine que cela fonctionnerait de la mĂȘme maniĂšre avec le module d'hĂ©bergement pour net core. La premiĂšre exĂ©cution arrĂȘte un peu le site, vous voudrez peut-ĂȘtre l'ajuster un peu.

param(
    [Parameter(Mandatory = $true)]
    [string] $iisRootPath,
    [Parameter(Mandatory = $true)]
    [string] $siteName,
    [Parameter(Mandatory = $true)]
    [string] $artifactPath,
    [Parameter(Mandatory = $false)]
    [string] $siteFolderName,
    [Parameter(Mandatory = $false)]
    [string] $appPoolName
)
Import-Module WebAdministration

#populate optional parameters
if (!($PSBoundParameters.ContainsKey('siteFolderName'))) { $siteFolderName = $siteName }
if (!($PSBoundParameters.ContainsKey('appPoolName'))) { $appPoolName = $siteName }

#set A, B and C paths
$a = "$iisRootPath\$siteFolderName" + 'A'
$b = "$iisRootPath\$siteFolderName" + 'B'
$c = "$iisRootPath\$siteFolderName"

#existence test
$cName = Get-Item -Path $c -ErrorAction SilentlyContinue | Select-Object -ExpandProperty name -ErrorAction SilentlyContinue
$bName = Get-Item -Path $b -ErrorAction SilentlyContinue | Select-Object -ExpandProperty name -ErrorAction SilentlyContinue

#get the shudown timeout for the app pool
$shutdownTimeout = Get-WebConfigurationProperty -Filter 'system.web/httpRuntime' -PSPath "IIS:\Sites\$siteName" -Name shutdownTimeout | Select-Object -ExpandProperty Value

#create symlink, if symlink source is an existing directory, rename existing 
if($cName -eq $null) 
{
    Write-Output "Creating SymbolicLink $c -> $a" 
    New-Item -Type SymbolicLink -Path $c -Target $a
} 
else
{
    #directories don't have a target property
    $cTarget = Get-Item -Path $c | Select-Object -ExpandProperty target -ErrorAction SilentlyContinue

    #this is a directory, rename and create symlink
    if($cTarget -eq $null)
    {
        #restart AppPool first so no locked files
        #Write-Output "Restarting AppPool $appPoolName" 
        #Restart-WebAppPool -Name $appPoolName

        #stop AppPool first so no locked files
        Write-Output "Stopping AppPool $appPoolName" 
        Stop-WebAppPool -Name $appPoolName

        #sleep for shutdownTimeout
        Write-Output "Sleeping for $shutdownTimeout" 
        Start-Sleep -Seconds (([System.TimeSpan]::Parse("$shutdownTimeout").TotalSeconds) * 1.1)

        try {
             #if the rename fails, there are files in use. stop the script
            $newName = $siteFolderName + 'A'
            Write-Output "Renaming $c to $newName" 
            Rename-Item -Path $c -NewName $newName -ErrorAction Stop
        }
        catch {
            Write-Error -Message "Failed to rename $c to $newName due to files in use."

            #start AppPool 
            Write-Output "Starting AppPool $appPoolName due to failed folder rename. Consider trying again durring a time with reduced traffic." 
            Start-WebAppPool -Name $appPoolName

        }

        #create symlink
        Write-Output "Creating SymbolicLink $c -> $a" 
        New-Item -Type SymbolicLink -Path $c -Target $a

        #start AppPool 
        Write-Output "Starting AppPool $appPoolName" 
        Start-WebAppPool -Name $appPoolName

        #copy a to b to pick up directory permissions
        if($bName -eq $null) 
        {
            Write-Output "Copying Directory $a to $b"  
            robocopy $a $b /e /sec /sl
        }
    }
}

#existence test
$aName = Get-Item -Path $a -ErrorAction SilentlyContinue | Select-Object -ExpandProperty name -ErrorAction SilentlyContinue
$bName = Get-Item -Path $b -ErrorAction SilentlyContinue | Select-Object -ExpandProperty name -ErrorAction SilentlyContinue

#create if needed
if($aName -eq $null) 
{
    Write-Output "Creating Directory $a"  
    New-Item -Type Directory $a 
}
if($bName -eq $null) 
{
    Write-Output "Creating Directory $b"  
    New-Item -Type Directory $b 
}

#make sure site pointing to symlink
Write-Output "Pointing Website $siteName to Path $c" 
Set-ItemProperty "IIS:\Sites\$siteName" -name physicalPath -value $c

#restart so we know it's loading from symlink
Write-Output "Restarting AppPool $appPoolName" 
Restart-WebAppPool -Name $appPoolName

#sleep for shutdownTimeout 
Write-Output "Sleeping for $shutdownTimeout" 
Start-Sleep -Seconds ([System.TimeSpan]::Parse("$shutdownTimeout").TotalSeconds)

#get current symlink target and set new target
Get-Item -Path $c | Select-Object -ExpandProperty target
$current = (Get-Item -Path $c).Target
$newTarget = if ($current -eq $a) {$b} else {$a}

$fileOrDirectoryName = Get-Item $artifactPath | Select-Object -ExpandProperty name

#test for .zip
if(($fileOrDirectoryName).ToLower().EndsWith(".zip") -eq $true)
{
    #copy to temp location
    $guid = [System.Guid]::NewGuid()
    $tempPath = "$iisRootPath\temp-$guid"
    $tempDest = "$iisRootPath\temp-dest-$guid"

    Write-Output "Creating temp directory $tempPath" 
    New-Item -Type Directory $tempPath

    $artifactDirectory = [System.IO.Path]::GetDirectoryName($artifactPath)
    $artifactFile = [System.IO.Path]::GetFileName($artifactPath);

    #TODO: first robocopy arg needs to be a directory, not a file
    Write-Output "Copying archive from $artifactPath to $tempPath" 
    robocopy $artifactDirectory $tempPath $artifactFile

    #extract to temp destination (seems a failed extract can leave empty folders)
    Write-Output "Extracting archive to $tempDest" 
    Expand-Archive -Path "$tempPath\$fileOrDirectoryName" -DestinationPath $tempDest -Force

    #copy from temp destination to destination
    Write-Output "Copying files from $tempDest to $newTarget" 
    robocopy $tempDest $newTarget /e

    #delete temp directory
    Write-Output "Removing temp directory $tempPath" 
    Remove-Item -Path $tempPath -Recurse -Force

    #delete temp directory
    Write-Output "Removing temp directory $tempDest" 
    Remove-Item -Path $tempDest -Recurse -Force
}
else 
{
    #copy new files
    Write-Output "Copying files from $artifactPath to $newTarget" 
    robocopy $artifactPath $newTarget /e
}

#swap symlink
Write-Output "Pointing SymbolicLink $c -> $newTarget" 
New-Item -Type SymbolicLink -Path $c -Target $newTarget -Force

#restart so it loads from newly swapped symlink
Write-Output "Restarting AppPool $appPoolName" 
Restart-WebAppPool -Name $appPoolName

@LucidObscurity qu'est-ce que c'est? un code cmd? oĂč dois-je ajouter ce code?
Merci

Qu'en est-il de l'idée d'augmenter le nombre de tentatives (paramÚtre: -retryAttempts:X ) ou l'intervalle de temps de nouvelle tentative (paramÚtre: -retryInterval:XXXX ) pour la commande msdeploy , jusqu'à ce que le processus libÚre le verrou de fichier?

Je pense que @davidfowl a raison, le processus est toujours lĂ  et verrouille les fichiers. MĂȘme Reset IIS n'aide pas , il attend toujours le processus jusqu'Ă  l'expiration du dĂ©lai. Si vous supprimez app_offline.htm et attendez 90 secondes (paramĂštre de dĂ©lai d'expiration par dĂ©faut pour arrĂȘter AppPool), et rĂ©essayez, vous verrez que cela fonctionne.
Pour moi en local, je ne veux pas attendre aussi longtemps, j'ai donc mis Ă  jour cette limite de temps d'arrĂȘt (secondes) Ă  5 et mettre Ă  jour le fichier de projet pour gĂ©nĂ©rer app_offline.htm avant la construction, supprimez-le aprĂšs la construction. Ça marche bien.
Pour le serveur, j'utilise msdeploy pour supprimer app_offline.htm, synchroniser la nouvelle version, puis supprimer app_offline.htm. Avec msdeploy, il réessaye si les fichiers sont verrouillés mais parfois abandonnés avant 90 secondes, je dois donc déclencher à nouveau le déploiement, puis cela fonctionne à la deuxiÚme tentative

Une mise Ă  jour Ă  ce sujet? Quand cette nouvelle version sera-t-elle prĂȘte?

Merci de nous avoir contacté.
Nous déplaçons ce numéro vers le jalon Next sprint planning pour une évaluation / considération future. Nous évaluerons la demande lors de la planification des travaux pour la prochaine étape. Pour en savoir plus sur ce à quoi vous attendre et comment ce problÚme sera traité, vous pouvez en savoir plus sur notre processus de triage ici .

J'ai dĂ©couvert ce problĂšme cette semaine, aprĂšs avoir converti une application .NET 4.5.2 en .NET 5.0. J'ai une autre approche pour surmonter cela. J'ai crĂ©Ă© un service Windows qui s'exĂ©cute sur le serveur IIS. Sur ce service, j'ai un simple serveur HTTP fonctionnant sur un port personnalisĂ©. L'application Web peut effectuer une post-demande auprĂšs de ce serveur pour lancer une mise Ă  niveau. Il arrĂȘte le pool d'applications et s'assure de tuer tous les processus de cette application, de crĂ©er une sauvegarde de la version actuelle, de supprimer la version actuelle, de tĂ©lĂ©charger le package de mise Ă  niveau et de l'extraire. Puis redĂ©marre le pool d'applications.

J'ai créé une application Windows Forms simple, pour créer des packages de mise à niveau qui sont poussés vers un référentiel à partir duquel le service Windows mentionné ci-dessus extrait.

Cette page vous a été utile?
0 / 5 - 0 notes