2010-07-06 49 views
10

Durante el desarrollo, frecuentemente tengo que implementar un gran archivo war (~ 45 MB) en un servidor de prueba remoto, normalmente copio el archivo con scp en el servidor.Mejor forma de desplegar grandes * .war a tomcat

La carpeta WEB-INF/lib constituye la parte más grande del archivo war, que incluye todas las bibliotecas necesarias (spring, apache-cxf, hibernate, ...).

Ahora estoy buscando una forma rápida y fácil de volver a desplegar solo mis archivos alterados.

Y cómo puedo determinar qué paquetes realmente necesita la aplicación web, porque spring y apache-cxf vienen con muchas librerías, estoy seguro de que no las necesito todas.

Respuesta

5

Al implementar un .war, lo primero que hace es Tomcat para descomprimir ese archivo en el directorio webapps, en un subdirectorio con el mismo nombre que su .war.

Durante el desarrollo, obviamente tiene acceso a sus archivos .class, los archivos .jar, los archivos de configuración y cualquier otra cosa que eventualmente entre en su .war. Puede establecer fácilmente un pequeño subconjunto de archivos afectados por sus cambios. Compruébelo y luego use una secuencia de comandos o una tarea ant o lo que sea para copiar solo ese pequeño puñado de archivos directamente en el directorio webapps/yourapp en el servidor.

Para ver los cambios surtan efecto, deberá reiniciar su aplicación. Si Tomcat está en modo de desarrollo, una manera fácil de forzar una recarga (y reiniciar, por supuesto) es actualizar WEB-INF/web.xml. Así que tenga su proceso de implementación touch ese archivo o de lo contrario actualícelo de manera que le dé una nueva marca de tiempo, scp que también (preferiblemente como el último de los archivos que actualiza) y debe tener una recarga rápida y fácil.

0

No creo que haya una manera más rápida de volver a implementar solo los cambios en un archivo WAR.

Si despliega de manera explosiva puede ver qué archivos de marcas de tiempo han cambiado y actuar en consecuencia, pero tendrá que escribir el código para hacerlo.

No sé si OSGi puede ser una ayuda aquí. Eso le permitiría dividir su problema en módulos que son más independientes e intercambiables.

Sólo por curiosidad:

  1. ¿Cuánto tiempo se tarda ahora?
  2. ¿Utiliza integración continua para compilar e implementar?
+0

Por mayor problema es el tiempo de carga en el servidor remoto, el despliegue se auto corre rápido y limpio. Solo puedo probar la aplicación webapp en el servidor remoto, debido a la complejidad y complejidad del subsistema en el que se desarrolla la aplicación web. – Alex

2

Lo que hago es excluir los archivos WEB-INF/lib/*. Jar de WAR y volver a montar en el lado del servidor. En mi caso, esto reduce una WAR de 60MB a 250k lo que permite un despliegue realmente rápido.

El comando <exclude name="**/lib/*.jar"/> es lo excluye de la jarra (véase el último fragmento de código para la construcción ANT)

En el lado del servidor, es muy fácil de montar un WAR totalmente poblada de la guerra recortado:

  1. descomprimir/explotar la GUERRA recortado que fue creado por el script ANT continuación
  2. copiar los archivos jar en el repositorio del servidor explotado WEB-INF/lib
  3. postal es todo para arriba en una nueva (grande) GUERRA.
  4. despliegue como de costumbre.

Por ejemplo:

unzip ../myapp.trimmed.war 
mkdir WEB-INF/lib 
cp ../war_lib_repository/* WEB-INF/lib 
zip -r ../myapp.war . 

Quizás no sea la solución más elegante, pero ahorra tiempo en el despliegue frecuente de gran WAR de. Me gustaría poder hacer esto con Maven, así que si alguien tiene sugerencias, por favor avíseme.

ANT build.xml:

<property file="build.properties"/> 
<property name="war.name" value="myapp.trimmedwar"/> 
<property name="deploy.path" value="deploy"/> 
<property name="src.dir" value="src"/> 
<property name="config.dir" value="config"/> 
<property name="web.dir" value="WebContent"/> 
<property name="build.dir" value="${web.dir}/WEB-INF/classes"/> 
<property name="name" value="${war.name}"/> 

<path id="master-classpath"> 
    <fileset dir="${web.dir}/WEB-INF/lib"> 
     <include name="*.jar"/>   
    </fileset> 
    <!-- other classes to include --> 
    <fileset dir="${birt.runtime}/ReportEngine/lib"> 
     <include name="*.jar"/> 
    </fileset> 
    <pathelement path="${build.dir}"/> 
</path> 

<target name="build" description="Compile main source tree java files"> 
    <mkdir dir="${build.dir}"/> 
    <javac destdir="${build.dir}" debug="true" deprecation="false" optimize="false" failonerror="true"> 
     <src path="${src.dir}"/> 
     <classpath refid="master-classpath"/> 
    </javac> 
</target> 

<target name="createwar" depends="build" description="Create a trimmed WAR file (/lib/*.jar) excluded for size"> 
    <!-- copy the hibernate config file --> 
    <copy todir="${web.dir}/WEB-INF/classes"> 
     <!-- copy hibernate configs --> 
     <fileset dir="${src.dir}/" includes="**/*.cfg.xml" /> 
    </copy>  
    <copy todir="${web.dir}/WEB-INF/classes"> 
     <fileset dir="${src.dir}/" includes="**/*.properties" /> 
    </copy>    
    <!-- copy hibernate classes --> 
    <copy todir="${web.dir}/WEB-INF/classes" > 
     <fileset dir="${src.dir}/" includes="**/*.hbm.xml" /> 
    </copy> 
    <war destfile="${name}.war" webxml="${web.dir}/WEB-INF/web.xml"> 
     <fileset dir="${web.dir}"> 
      <include name="**/*.*"/> 
      <!-- exlude the jdbc connector because it's on the server's /lib/common --> 
      <exclude name="**/mysql-connector*.jar"/> 
      <!-- exclude these jars because they're already on the server (will be wrapped into the trimmed war at the server) --> 
      <exclude name="**/lib/*.jar"/> 
     </fileset> 
    </war> 
    <copy todir="${deploy.path}" preservelastmodified="true"> 
     <fileset dir="."> 
      <include name="*.war"/> 
     </fileset> 
    </copy> 
</target>   

1

utilizo rsync a copiar mi .war de mi máquina local para la producción. Por lo general, proporciona una gran velocidad, alrededor de 8 a 10 veces.

Otra opción es usar git para almacenar los archivos .war. Cuando git push un nuevo .war, solo se transfieren las diferencias. También una gran velocidad. Algunas personas dicen que git no está diseñado para almacenar archivos grandes, se vuelve lento y no funciona muy bien. De hecho, sí, el repositorio crecerá mucho, pero en algunos casos podría ser una buena opción.

Algunos números: Mi .war es de aproximadamente 50MB y cuando despliego una nueva versión, solo copia unos ~ 4MB en lugar de cargar una nueva guerra completa. Ambos con git y rsync.

ACTUALIZACIÓN: El problema me encontré con que es el repositorio git no puede ser clonado después de tener varias versiones .war porque va a tener siempre a crear todos los deltas y transmitirlos al cliente.

me cambió la estrategia mediante la carga de los archivos en Dropbox .war. Dropbox también usa tipo de rsync y solo copia deltas. Desde el servidor, administro el .war y vuelvo a implementar la aplicación. Espero que esto ayude.

+0

'rsync' es tremendamente rápido! Solo unos segundos en lugar de 5-7 minutos para mi aplicación. La depuración es tan rápida como en la máquina local. ¡Muchas gracias! –

Cuestiones relacionadas