¿Cómo hacer que IIS7 libere un archivo bloqueado?

25

Durante nuestras compilaciones de producción, IIS a veces bloquea un archivo de contenido estático muy grande (10 megabytes) en el directorio raíz y la tarea de limpieza no puede eliminarlo. Presumiblemente, esto se debe a que se atiende activamente a uno o más clientes en ese momento.

El proceso de compilación detiene el sitio web antes de limpiarlo a través de

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

Sin embargo, esto no libera el archivo; tenemos que reiniciar IIS para que el proceso renuncie a su bloqueo.

appcmd.exele permite eliminar IIS por completo; que no queremos hacer esto!

¿Hay alguna otra forma de hacer que IIS suelte un archivo bloqueado sin reiniciar IIS? Simplemente detener e iniciar el sitio web individual definitivamente no funciona para liberar el bloqueo de archivos.

Jarrod Dixon
fuente
1
Pregunta seria ahora: ¿este archivo estático cambia de compilación a compilación o es solo un archivo que nunca cambiará?
splattne
Solo un pensamiento loco, pero me pregunto qué pasaría si habilitaras Shadow Copies en esta carpeta.
Richard West
Este es su sitemap.xml ¿verdad?
Dave Cheney
Sí, era nuestro sitemap.xml, pero ahora solo tenemos una ruta MVC y almacenamos el lechón en la memoria. ¡No más bloqueos!
Jarrod Dixon

Respuestas:

12

Existen herramientas, como el Explorador de procesos de Sysinternal, que pueden encontrar y cerrar por la fuerza los identificadores de archivos, sin embargo, el estado y el comportamiento de la aplicación (tanto la suya como, en este caso, IIS) después de hacerlo no está definida. A algunos no les importará, algunos se equivocarán y otros se estrellarán con fuerza.

La solución correcta es tomar la interrupción y permitir que IIS libere los bloqueos y se limpie después de sí mismo para preservar la estabilidad del servidor. Si esto no es posible, puede crear otro sitio en el mismo cuadro o configurar un nuevo cuadro con el nuevo contenido y mover el nombre de dominio / IP para "promover" el nuevo contenido a producción.

Greg trabajo
fuente
2
1 para el explorador de procesos, le puede dar una idea de ser capaz de resolver el problema si se puede ver lo que el hilo está sosteniendo el identificador de archivo abierto
Nick Kavadias
Tal vez sea muy útil el archivo bloqueado lanzado mediante programación utilizando herramientas Sysinternals con Powershell , C # o scripts bat-cmd
Kiquenet
Tengo IIS para desbloquear el archivo o directorio simplemente tratando de copiar archivos en esa carpeta controlada por IIS y luego viendo la aplicación web en un navegador. A veces, este proceso desbloquea esos identificadores.
Marc Noon
13

Utilizo una pequeña herramienta llamada "Manejar" para hacer esto.

Básicamente le pasa el nombre del archivo que está bloqueado y le dice qué procesos lo están usando:

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

Luego le pasa el interruptor -c para que cierre el controlador:

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

Es posible que tenga dificultades para trabajar en un script de compilación sin un programa contenedor para analizar la salida, pero espero que esto ayude.

Simon Johnson
fuente
El poderoso Mark Russinovich al rescate: lo comprobaré, pero la grave advertencia de Handle sobre la inestabilidad del programa al cerrar por la fuerza una manija me pone nervioso.
Jarrod Dixon
Esperemos que cualquier inestabilidad se limite al AppPool en cuestión. Si ese es el caso, puede reiniciar AppPool después de liberar el bloqueo.
Simon Johnson
@ Jarrod: ¿alguna suerte? ¿Podría publicar algún resultado, en su publicación original, por favor? Me encantaría ver lo que está sucediendo aquí, detrás de escena.
Pure.Krome
Tal vez sea muy útil el archivo bloqueado lanzado mediante programación utilizando Handle con Powershell , C # o scripts bat-cmd y obtenga procesos que bloquean una carpeta
Kiquenet
5

No estoy seguro de si te refieres a la compilación de archivos aspx en ensamblajes temporales. Estamos utilizando proyectos de implementación de ASP.NET , que precompilan todos los archivos aspx / ascx de antemano.

Al copiar los archivos binarios de la "publicación" a la carpeta "bin", habilitamos temporalmente un archivo app_offline.htm que se elimina después de que se copian todos los ensamblajes (solo unos segundos). De esta manera nunca experimenté bloqueos de archivos.

EDITAR:

Puede intentar reciclar el grupo de aplicaciones usando appcmd.exe, en lugar de detener el sitio web:

C:\Windows\System32\inetsrv\appcmd.exe recycle apppool "My App Pool Name"
splattne
fuente
1
No, es solo un archivo de contenido estático en el directorio raíz, ¡actualizando la pregunta con esa información!
Jarrod Dixon
1
¿Supongo que estás usando app_offline.htm durante la ejecución de tu trabajo de compilación?
splattne
Creo que hemos intentado reciclar manualmente en vano, pero lo intentaremos nuevamente la próxima vez que haya un bloqueo (los grupos de aplicaciones son para .NET, ¿verdad? Probablemente no ayude aquí). Y solíamos crear el archivo app_offline.htm, pero no ayudó con el bloqueo, razón por la cual pasamos a eliminar el sitio individual.
Jarrod Dixon
Me temo que tienes razón. Probaré esto en uno de nuestros servidores y volveré a usted.
splattne
1
@splattne: Reciclar el grupo de aplicaciones debería haber eliminado el identificador siempre que el sitio web haya abierto el archivo. Si reciclar el grupo no ayuda, supongo que algo más bloquea el archivo.
pbz
1

Process Monitor debería ayudarlo con su investigación, aquí hay un ejemplo del blog de Mark ( el tipo que escribió la herramienta) sobre cómo encontrar el identificador de archivo.

Es posible que desee probar esta herramienta de desbloqueo para automatizar su desbloqueo a nivel de controlador de archivos.

Nick Kavadias
fuente
Genial, nunca he usado Process Monitor; ¡pero cada estación de trabajo que uso inmediatamente obtiene Process Explorer! technet.microsoft.com/en-us/sysinternals/bb896653.aspx
Jarrod Dixon
1

No es la respuesta, pero es una idea alternativa en caso de que no haya forma de "desbloquear" ese archivo sin reiniciar el servidor IIS:

¿Qué sucede si crea / implementa en una nueva carpeta vacía y cambia el directorio de inicio del sitio web a esa carpeta? Sin embargo, debe crear un nuevo nombre de carpeta o cambiar entre dos nombres.

No sé a qué carpeta pertenece ese archivo. Si no tiene que estar en la carpeta raíz, puede colocarlo en una carpeta recién creada y crear un directorio virtual que apunte a esa carpeta. Para que pueda mantener su directorio de inicio estándar para la aplicación.

splattne
fuente
1

Yo tuve el mismo problema. Ahora cambié a MSDeploy (Web Deploy) , y ahora puedo actualizar el sitio web de manera confiable sin detener nada. De hecho, este paso está programado en nuestra herramienta de compilación automatizada y ocurre todo el tiempo sin ningún problema. Y también es rápido.

realMarkusSchmidt
fuente
0

Claro, detenga el servicio IIS. Tal vez no entiendo algo, lo siento.

Mark Allen
fuente
2
Si usted se detiene el servicio IIS, podrás acabar con todos los sitios web ...
splattne
Eso es lo único que realmente queremos evitar, ya que no queremos que nuestro sitio CruiseControl.NET se caiga: ¡hacemos clic en el botón "Actualizar estado" como locos durante una compilación para verificar el éxito!
Jarrod Dixon
Ok, ¿qué tal construir primero en otro lugar, luego implementar sobre el archivo estático en lugar de hacer todo en ese servidor?
Mark Allen
¿No es ese el problema aquí? Nadie dijo que el software estaba modificando el archivo en el servidor.
FlavorScape
0

nota: no es un experto en semántica de bloqueo de archivos de Windows

Jarrod, ¿puedes cambiar el nombre del archivo? También puede crear su nuevo archivo con una extensión temporal y luego renombrarlo sobre el archivo actual.

Si la semántica de bloqueo de archivos de Windows funciona de manera similar a POSIX, los lectores que mantienen un bloqueo de lectura actual en el archivo, aún deben continuar sirviendo el archivo antiguo hasta que cierren sus secuencias de lectura, mientras que los nuevos lectores abrirán el nuevo archivo.

Dave Cheney
fuente
No, no podemos hacer nada al archivo hasta que se reinicie IIS.
Jarrod Dixon