Jak zmusić IIS7 do wydania zablokowanego pliku?

25

Podczas naszych kompilacji produkcyjnych bardzo duży (10 megabajtów) plik zawartości statycznej w katalogu głównym jest czasami blokowany przez IIS i nie może zostać usunięty przez czyste zadanie. Jest tak prawdopodobnie dlatego, że w tym czasie jest on aktywnie obsługiwany przez jednego lub więcej klientów.

Proces kompilacji zatrzymuje witrynę przed czyszczeniem

c:\Windows\System32\inetsrv\appcmd.exe stop site http://oursite.com

Jednak to nie zwolnić pliku - trzeba ponownie uruchomić usługi IIS, aby proces zrezygnować z jego blokadę.

appcmd.exepozwala całkowicie zdjąć IIS; my nie chcemy tego robić!

Czy istnieją inne sposoby zmuszenia IIS do zwolnienia zablokowanego pliku bez ponownego uruchamiania IIS? Samo zatrzymanie i uruchomienie pojedynczej witryny zdecydowanie nie działa, aby zwolnić blokadę pliku.

Jarrod Dixon
źródło
1
Poważne pytanie: czy ten plik statyczny zmienia się z kompilacji na kompilację, czy jest to tylko plik, który nigdy się nie zmieni?
splattne
To tylko szalona myśl, ale zastanawiam się, co by się stało, gdybyś włączył kopie w tle w tym folderze?
Richard West,
To jest twój sitemap.xml, prawda?
Dave Cheney
Tak, to był nasz sitemap.xml, ale teraz mamy tylko trasę MVC i buforujemy przyssawkę w pamięci. Nigdy więcej blokowania!
Jarrod Dixon

Odpowiedzi:

12

Istnieją narzędzia, takie jak Sysinternal's Process Explorer, które mogą wyszukiwać i wymuszać zamykanie uchwytów plików, jednak stan i zachowanie aplikacji (zarówno twojej, jak i, w tym przypadku IIS) po wykonaniu tej czynności jest nieokreślone. Niektórym to nie obchodzi, niektórzy będą błądzić, a inni mocno się rozbiją.

Prawidłowym rozwiązaniem jest wyeliminowanie awarii i umożliwienie IIS czystego zwolnienia blokad i czyszczenia po sobie, aby zachować stabilność serwera. Jeśli nie jest to możliwe, możesz utworzyć inną witrynę w tym samym pudełku lub skonfigurować nowe pudełko z nową zawartością i przenieść nazwę domeny / adres IP, aby „promować” nową zawartość do produkcji.

Greg Work
źródło
2
+1 dla eksploratora procesów, może dać ci wgląd w możliwość rozwiązania problemu, jeśli zobaczysz, który wątek trzyma otwarty uchwyt pliku
Nick Kavadias
Być może bardzo przydatny wydany zablokowany plik programowo za pomocą narzędzi Sysinternals z Powershell , C # lub skryptami bat-cmd
Kiquenet
Mam IIS do odblokowania pliku lub katalogu, po prostu próbując skopiować pliki do tego folderu kontrolowanego przez IIS, a następnie przeglądać aplikację internetową w przeglądarce. Czasami ten proces odblokowuje te uchwyty.
Marc Noon
13

Używam do tego małego narzędzia o nazwie „Uchwyt” .

Zasadniczo przekazujesz mu nazwę pliku, który jest zablokowany, i informuje, jakie procesy go wykorzystują:

handle c:\weird.file
Something.exe pid: 1000 100: C:\weird.file
Something.exe pid: 1000 101: C:\weird.file

Następnie podajesz przełącznik -c, aby zamknąć uchwyt:

handle.exe -c 101 -p 1000 -y
handle.exe -c 100 -p 1000 -y

Możesz mieć problem z włączeniem tego do skryptu kompilacji bez programu opakowującego, aby przeanalizować dane wyjściowe, ale mam nadzieję, że to pomoże.

Simon Johnson
źródło
Potężny Mark Russinovich na ratunek - sprawdzę to, ale straszne ostrzeżenie Handle'a o niestabilności programu podczas przymusowego zamykania klamki denerwuje mnie.
Jarrod Dixon
Mamy nadzieję, że każda niestabilność będzie ograniczona do przedmiotowego AppPool. W takim przypadku możesz po prostu ponownie uruchomić AppPool po zwolnieniu blokady.
Simon Johnson
@ Jarrod: jakieś szczęście? Czy mógłbyś zamieścić jakieś wyniki w swoim pierwotnym poście? Chciałbym zobaczyć, co się dzieje tutaj, za kulisami.
Pure.Krome
Być może bardzo przydatny wypuścił zablokowany plik programowo za pomocą Handle with Powershell , C # lub skryptów bat-cmd i uzyskać procesy blokujące folder
Kiquenet
5

Nie jestem pewien, czy masz na myśli kompilację plików aspx w zespołach tymczasowych. Korzystamy z projektów wdrażania ASP.NET , które wstępnie kompilują wszystkie pliki aspx / ascx.

Podczas kopiowania plików binarnych z folderu „publikuj” do folderu „bin” tymczasowo włączamy plik app_offline.htm, który jest usuwany po skopiowaniu wszystkich zestawów (zaledwie kilka sekund). W ten sposób nigdy nie doświadczyłem blokady plików.

EDYTOWAĆ:

Możesz spróbować odtworzyć pulę aplikacji za pomocą appcmd.exe, zamiast zatrzymywania strony internetowej:

C:\Windows\System32\inetsrv\appcmd.exe recycle apppool "My App Pool Name"
splattne
źródło
1
Nie, to tylko statyczny plik zawartości w katalogu głównym - aktualizacja pytania o te informacje!
Jarrod Dixon
1
Zgaduję, że używasz app_offline.htm podczas sprawdzania swojego zadania kompilacji?
splattne
Myślę, że próbowaliśmy recyklingu ręcznie, ale bezskutecznie, ale spróbujemy ponownie następnym razem, gdy pojawi się blokada (pule aplikacji są dla .NET, prawda? Prawdopodobnie nie pomoże tutaj). Kiedyś tworzyliśmy plik app_offline.htm, ale to nie pomogło w blokowaniu - dlatego przenieśliśmy się na usunięcie pojedynczej witryny.
Jarrod Dixon
Obawiam się, że masz rację. Przetestuję to na jednym z naszych serwerów i wrócę do ciebie.
splattne
1
@splattne: Recykling puli aplikacji powinien usunąć uchwyt, pod warunkiem że plik został otwarty przez witrynę internetową. Jeśli recykling puli nie pomoże, to przypuszczam, że coś innego blokuje plik.
pbz
1

Nie odpowiedź, ale sposób obejścia tego problemu w przypadku, gdy nie ma możliwości „odblokowania” tego pliku bez ponownego uruchomienia serwera IIS:

Co się stanie, jeśli zbudujesz / wdrożysz w nowym pustym folderze i zmienisz katalog domowy strony internetowej na ten folder? Musisz jednak utworzyć nową nazwę folderu lub przełączać się między dwiema nazwami.

Nie wiem, do którego folderu należy ten plik. Jeśli nie musi znajdować się w folderze głównym, możesz umieścić go w nowo utworzonym folderze i utworzyć katalog wirtualny wskazujący ten folder. Możesz więc zachować standardowy katalog domowy dla aplikacji.

splattne
źródło
1

Miałem ten sam problem. Teraz przełączyłem się na MSDeploy (Web Deploy) , a teraz mogę w niezawodny sposób aktualizować witrynę bez zatrzymywania czegokolwiek. W rzeczywistości ten krok jest zapisany w skrypcie w naszym narzędziu do automatycznej kompilacji i odbywa się cały czas bez żadnych problemów. I to też jest szybkie.

realMarkusSchmidt
źródło
0

Jasne, zatrzymaj usługę IIS. Może nie rozumiem czegoś, przepraszam.

Mark Allen
źródło
2
Jeśli zatrzymujesz usługę IIS,
usuniesz
Jest to jedyna rzecz, której naprawdę chcemy uniknąć, ponieważ nie chcemy, aby nasza strona CruiseControl.NET upadła - klikamy ten przycisk „Odśwież status” jak szaleni podczas kompilacji, aby sprawdzić sukces!
Jarrod Dixon
Ok, a może najpierw zbudujesz gdzieś indziej, a następnie wdrożysz plik statyczny zamiast robić wszystko na tym serwerze?
Mark Allen
czy to nie jest problem? Nikt nie powiedział, że plik jest modyfikowany przez oprogramowanie na samym serwerze.
FlavorScape,
0

Uwaga: nie jest ekspertem od semantyki blokowania plików systemu Windows

Jarrod, czy możesz zmienić nazwę pliku na uboczu? Możesz także utworzyć nowy plik z tymczasowym rozszerzeniem, a następnie zmienić jego nazwę na bieżący plik.

Jeśli semantyka blokowania plików systemu Windows działa podobnie do POSIX, czytniki, które posiadają bieżącą blokadę odczytu pliku, powinny nadal obsługiwać stary plik, dopóki nie zamkną swoich strumieni odczytu, a nowe czytniki otworzą nowy plik.

Dave Cheney
źródło
Nie, nie możemy nic zrobić z plikiem, dopóki IIS nie zostanie ponownie uruchomiony.
Jarrod Dixon