2009-12-07 21 views
5

Tenemos una aplicación que se ejecuta como un servicio de Windows en un servidor de producción. La aplicación está dividida en varios ensambles principalmente en límites de despliegue. Me gustaría simplificar la implementación de arreglos urgentes para ensambles de aplicaciones. Actualmente realizo los siguientes pasos para implementar una solución hotfix. (Tenemos un duplicado del entorno de producción para la puesta en escena, así que todo tiene que ser hecho dos veces)Despliegue en caliente de ensamblados .net

  1. de sesión en el servidor
  2. Detener el servicio
  3. de copia de seguridad DLL actualmente desplegados
  4. Reemplazar con la revisión (Copia revisión sobre DLL existente)
  5. Reiniciar servicio
  6. rollo de nuevo en caso de errores de carga inesperadas (no ha sucedido, sin embargo)

Creo que lo que me gustaría es cargar (SFTP) una DLL a una carpeta preestablecida y hacer que la aplicación recoja la nueva DLL.

Una solución que he considerado es tener un servicio separado ejecutándose en el servidor. Vamos a llamarlo un servicio de implementación de revisiones. Vería el sistema de archivos para nuevos archivos y realizará los pasos 2 a 6 de la lista anterior.

Cualquier idea es apreciada. Estoy abierto a otras alternativas y siempre que reduzcan la fricción de implementación.

Respuesta

4

Tener un servicio separado es probablemente su mejor opción.

Podría, potencialmente, hacer esto en un solo servicio. Sin embargo, el "truco" que se requeriría para hacer una actualización automática del servicio es un poco difícil de implementar.

Lo que tendría que hacer es comenzar su servicio como un servicio de shell muy liviano. Luego podría comenzar un AppDomain aislado y aislado, y hacer que el dominio de aplicación cargue los ensamblajes de su servicio, se inicialice y se ejecute.

Más tarde, cuando deseaba actualizar (que podría desencadenarse a través de cualquier evento que el servicio pueda recoger, incluida la copia de los nuevos ensamblajes a una carpeta de actualización [a través de FileSystemWatcher], explícitamente a través de redes, etc.]) tendría que desencadenar una forma de indicar el tipo de dominio de aplicación interno para detener, luego descargar el dominio de aplicación. En este punto, podría hacer los pasos 3 & 4 arriba. Luego, solo necesitaría volver a cargar AppDomain, volver a ejecutar su inicialización, etc.

Dado que el servicio estaría en un Dominio de aplicaciones separado, todo esto podría suceder en un ejecutable, sin que el servicio se detuviera. Cuando un AppDomain está descargado, los ensamblajes que carga también se descargan.

El único requisito aquí que lo hace difícil es que debe asegurarse de no pasar ningún tipo en el dominio de aplicación principal del construido, o cargará los ensamblajes en su dominio de aplicación principal. Esto evitaría que pueda actualizarlos en tiempo de ejecución.

+1

ShadowCopyFiles es enorme aquí. –

+0

Sí, aunque con los requisitos de copia de seguridad, puede ser un problema menor en este caso específico. –

+0

El paso de la copia de seguridad no es un requisito difícil, es solo un paso que debo dar para poder retroceder rápidamente. No estoy familiarizado con ShadowCopyFiles, tengo que investigar eso. –

1

me gustaría echar un vistazo a Castle Windsor como una buena opción para los conjuntos de "conexión en caliente".

Es un marco de IoC/DI avanzado y bien soportado que ayuda con muchas de las tareas que menciona, a excepción de mover los archivos a la máquina de destino. Sin embargo, las cañerías en sí serían bien atendidas con CW.

+0

Ya estamos usando un contenedor IoC (Unity), pero no estoy seguro de cómo eso haría el intercambio en caliente de tipos cargados. ¿Castle tiene algo en esta área? (Una mirada rápida al sitio web no reveló nada) –

+0

Sí. Tendrás que profundizar un poco más, pero el intercambio en caliente fue uno de los objetivos principales de CW (la última vez que miré de todos modos). ¿La unidad no es compatible con el intercambio en caliente? Sorprendente. Pero el simple hecho de que ya esté usando un marco DI debería ayudarlo a migrar con bastante facilidad. –

+0

Supongo que depende de la definición de "intercambio en caliente". Por ejemplo, si tiene varias implementaciones de una interfaz, puede resolver cualquier implementación dada. Pero necesito reemplazar una implementación concreta después de que se haya resuelto y la aplicación la esté utilizando. No se me ocurrió buscar esto en Unity, pero estoy bastante seguro de que no puedes hacer eso. Después de que construyes el contenedor y se carga un tipo, está prácticamente atorado en el dominio de aplicación (a menos que me falte algo) –

2

Desde nuestro servidor de compilación, utilizamos una secuencia de comandos de powershell para detener el servicio de forma remota, copiar el nuevo archivo y reiniciar el servicio.

+0

Hacemos casi exactamente esto de CruiseControl.NET. (Sin powershell). –

Cuestiones relacionadas