2008-09-24 12 views
18

Tenemos una aplicación de servidor Java que se ejecuta en varias computadoras, todas conectadas a Internet, algunas detrás de firewalls. Necesitamos actualizar de forma remota los archivos JAR y los scripts de inicio desde un sitio central, sin interrupciones notables en la aplicación.¿Cómo se actualizan las aplicaciones Java de manera remota?

El proceso debe ser desatendido y seguro (es decir, no podemos darnos el lujo de romper la aplicación debido a interrupciones intempestivas de Internet).

En el pasado hemos utilizado una variedad de scripts y utilidades externas para manejar tareas similares, pero debido a que tienen sus propias dependencias, el resultado es más difícil de mantener y menos portátil. Antes de hacer algo nuevo, quiero obtener información de la comunidad.

¿Alguien ha encontrado una buena solución para esto ya? ¿Tienes alguna idea o sugerencia?

Solo para aclarar: Esta aplicación es un servidor, pero no para aplicaciones web (no hay contenedores de webapp o archivos WAR aquí). Es solo un programa Java autónomo.

Respuesta

6

No especificó el tipo de aplicaciones de servidor: supongo que no está ejecutando aplicaciones web (ya que la implementación de WAR ya hace lo que está diciendo, y muy rara vez necesita una aplicación web). para hacer actualizaciones de tipo pull. Si está hablando de una aplicación web, la siguiente discusión aún se puede aplicar: implementará la verificación de actualización y ping-pong para el archivo WAR en lugar de archivos individuales).

Puede que quiera echar un vistazo a jnlp: WebStart se basa en esto (esta es una tecnología de implementación de aplicaciones cliente), pero estoy bastante seguro de que podría adaptarse para realizar actualizaciones para una aplicación tipo servidor. A pesar de todo, jnlp hace un buen trabajo al proporcionar descriptores que se pueden usar para descargar las versiones requeridas de los JAR necesarios ...

Algunas consideraciones generales sobre esto (tenemos varias aplicaciones en el mismo segmento, y estamos considerando un auto- mecanismo de actualización):

  1. Considere hacer que un archivo bootstrap.jar que es capaz de leer un archivo jnlp y descargar frascos requeridos/actualizados antes de iniciar la aplicación.

  2. archivos se pueden actualizar incluso mientras se está ejecutando una aplicación (al menos en Windows, y ese es el sistema operativo que más probabilidades tiene de mantener bloqueos al ejecutar archivos). Puede encontrarse con problemas si está utilizando cargadores de clases personalizados, o si tiene varios JAR que pueden cargarse o descargarse en cualquier momento, pero si crea mecanismos para evitar esto, sobrescribiendo los JAR y luego relanzando la aplicación debe ser suficiente para la actualización.

  3. Aunque es posible sobrescribir JAR, es posible que desee considerar un enfoque de ping-pong para su ruta de lib (si todavía no tiene el iniciador de aplicaciones configurado para leer automáticamente todos los archivos jar de lib carpeta y agregarlos a la ruta de clase de forma automática, entonces eso es algo que realmente desea hacer). Así es como funciona ping-pong:

lanza una aplicación y la mira de ping-lib \ version.properties y lib-pong \ version.properties y determina qué es más reciente. Digamos que lib-ping tiene una versión posterior. El iniciador busca lib-ping * .jar y agrega esos archivos al CP durante el lanzamiento. Cuando hace una actualización, descarga archivos jar en lib-pong (o copia archivos jar de lib-ping si quiere ahorrar ancho de banda y el JAR en realidad no cambió; ¡aunque esto rara vez vale la pena!). Una vez que haya copiado todos los archivos JAR en lib-pong, lo último que debe hacer es crear el archivo version.properties (de ese modo, se puede detectar y purgar una actualización interrumpida que da como resultado una carpeta lib parcial). Finalmente, reinicia la aplicación y el programa de arranque detecta que lib-pong es el classpath deseado.

  1. ping-pong como se describe arriba permite un retroceso. Si lo diseñas correctamente, puedes tener una parte de tu aplicación que pruebes y, a continuación, nunca cambies esa comprobación para ver si se debe retrotraer una versión determinada. De esta forma, si se equivoca y despliega algo que rompe la aplicación, puede invalidar la versión. Esta parte de la aplicación solo tiene que eliminar el archivo version.properties de la carpeta bad lib- * y luego volver a ejecutarlo. Es importante mantener esta parte simple de la suciedad porque es su falla.

  2. Puede tener más de 2 carpetas (en lugar de ping/pong, solo tiene lib-aaaammdd y purga todo menos el 5 más nuevo, por ejemplo). Esto permite una reversión más avanzada (¡pero más complicada!) De los JAR.

+0

Sí, su suposición es correcta: no estamos utilizando la implementación de WAR. La aplicación es un servidor, pero no para aplicaciones web. Gracias por la información sobre JNLP. Ahora estoy investigando ... –

3

Recomendaría Capistrano para la implementación de varios servidores. Si bien está diseñado para implementar aplicaciones Rails, he visto que se utilizó con éxito para implementar aplicaciones Java.

Enlace: Capistrano 2.0 Not Just for Rails

2

tarros no pueden ser modificados, mientras que la JVM se ejecuta en la parte superior de la misma y dará lugar a errores. He intentado tareas similares y lo mejor que se me ocurrió es hacer una copia del Jar actualizado y hacer la transición del script de inicio para ver ese Jar. Una vez que tenga el Jar actualizado, enciéndalo y espere a que termine el jar viejo antes de darle la señal para hacerlo. Desafortunadamente esto significa una pérdida de GUI, etc. durante un segundo, pero la serialización de la mayoría de las estructuras en Java es fácil y la GUI actual podría transferirse a la aplicación actualizada antes de que se cierre (¡aunque algunas cosas pueden no ser serializables!).

1

Creo que se puede desplegar en caliente archivos JAR si utiliza un servidor de aplicaciones basadas en OSGi como SpringSource dm Server. Nunca lo he usado, pero conociendo la calidad general de la cartera de Spring, estoy seguro de que vale la pena echarle un vistazo.

2

Es muy difícil hacer la actualización atómica, especialmente si tiene alguna actualización de base de datos que hacer.

Pero, si no lo hace, lo primero que puede hacer es asegurarse de que la aplicación se ejecute desde una ruta relativa. Es decir, puede colocar su aplicación en algún directorio, y todos los archivos importantes se encuentran relacionados con esa ubicación, de modo que su ubicación de instalación real no es realmente importante.

A continuación, duplique su instalación. Ahora, tienes la versión "en ejecución" y tienes la versión "nueva".

Actualice la versión "nueva" utilizando la tecnología que desee (FTP, rsync, cinta de papel, lo que sea que flote su barco).

Verifique su instalación (sumas de verificación, pruebas de unidades rápidas, lo que necesite, incluso si lo desea, inícielo en un puerto de prueba).

Cuando esté satisfecho con la nueva instalación, ejecute la instancia de ejecución original, RENOMBRAR el directorio original (mv application_old), cambie el nombre del directorio NEW (mv application_new) e inícielo nuevamente.

Su tiempo de inactividad se reduce al cierre del servidor y al tiempo de inicio (dado que el cambio de nombre es "libre").

Si, por casualidad, detecta un error crítico, tiene su versión original allí. Detener el nuevo servidor, cambiarle el nombre, reiniciar el antiguo. Muy rápido retrocede.

La otra cosa agradable es que su infraestructura de servicio es estática (como sus scripts rc, trabajos cron, etc.) ya que apuntan al directorio "aplicación", y no cambia.

También se puede hacer con enlaces suaves en lugar de cambiar el nombre de los directorios. de cualquier manera está bien.

Pero la técnica es simple, y casi a prueba de balas si su aplicación coopera.

Ahora, si tienes cambios en la base de datos, bueno, ese es un problema desagradable completamente diferente. Idealmente, si puede hacer que sus cambios DB sean "compatibles con versiones anteriores", entonces con suerte la versión anterior de la aplicación se puede ejecutar en el nuevo esquema, pero eso no siempre es posible.

4

Sin duda, debe echar un vistazo a OSGi, fue creado solo para estos casos (especialmente para productos integrados) y es utilizado por un gran número de empresas. Puede actualizar los "paquetes" de jar, agregarlos y eliminarlos mientras la aplicación se está ejecutando. No he utilizado yo mismo, así que no saber acerca de la calidad de los marcos de código/servidores abiertos, pero aquí hay un montón de enlaces útiles para empezar:

http://www.osgi.org/Main/HomePage
http://www.aqute.biz/Code/Bnd
http://blog.springsource.com/2008/02/18/creating-osgi-bundles/
http://blog.springsource.com/
http://www.knopflerfish.org/
http://felix.apache.org/site/index.html

0

Utilizamos Eclipse, que el sistema de actualización de OSGi, y nuestra experiencia es muy buena.

¡Recomendado!

0

La última versión de Java Web Start permite inyectar una aplicación en la memoria caché local sin invocar realmente el programa y se puede marcar como "fuera de línea". Como el caché es lo que se utiliza para invocar el programa, se actualizará solo para la próxima ejecución. Para que esto funcione, lo más probable es que necesite jarras con números de versión en su nombre (por ejemplo, our-library-2009-06-01.jar).

Cuestiones relacionadas