2010-07-06 20 views
10

Durante lo sviluppo Mi capita spesso di dover implementare una grande guerra del file (~ 45 MB) per un server di prova remoto, di solito mi copia il file con SCP al server.Il modo migliore per distribuire grandi * .war di Tomcat

La cartella WEB-INF/lib costituisce la parte più grande del file war, che include tutte le librerie richieste (spring, apache-cxf, hibernate, ...).

Ora sto cercando un modo semplice e veloce per ridistribuire solo i miei file alterati.

E come posso determinare quali pacchetti sono realmente necessari per la webapp, perché spring e apache-cxf vengono forniti con molte librerie, sono sicuro che non ho bisogno di tutti loro.

risposta

5

Quando si distribuisce un .war, la prima cosa che fa è Tomcat per decomprimere il file nella sua directory webapps, in una sottodirectory con lo stesso nome del .war.

Durante lo sviluppo, è ovviamente possibile accedere ai file .class, ai file .jar, ai file di configurazione e a qualsiasi altro elemento eventualmente incluso nel proprio .war. Puoi facilmente stabilire un piccolo sottoinsieme di file interessati dalle tue modifiche. Scoprilo, quindi usa uno script o un'attività ant o qualsiasi altra cosa per copiare solo quella piccola manciata di file direttamente nella directory webapps/yourapp sul server.

per visualizzare le modifiche abbiano effetto, è necessario riavviare l'applicazione. Se Tomcat è in modalità di sviluppo, un modo semplice per forzare una ricarica (e riavviare, ovviamente) è aggiornare WEB-INF/web.xml. Così il tuo processo di distribuzione è touch o lo aggiorna in un modo che gli darà un nuovo timestamp, scp troppo (preferibilmente come l'ultimo dei file che aggiorni) e dovresti avere un ricaricamento facile e veloce.

0

non credo che ci sia un modo più veloce di ridistribuire solo le modifiche apportate a un file WAR.

Se si distribuisce in modo esploso è possibile vedere ciò che i timestamp di file sono cambiati e agire di conseguenza, ma dovrete scrivere il codice per farlo.

Non so se OSGi può essere di aiuto qui. Ciò consentirebbe di suddividere il problema in moduli più indipendenti e in grado di scambiare.

Solo curioso:

  1. Quanto tempo ci vuole adesso?
  2. Utilizzi l'integrazione continua per creare e distribuire?
+0

Per il problema più grande è il tempo di caricamento sul server remoto, la distribuzione che esegue autonomamente è veloce e pulita. Posso solo testare la webapp del foro sul server remoto, a causa del sottosistema hudge e complicazione su cui si sviluppa la webapp. – Alex

2

Quello che faccio è esclude WEB-INF/lib/*. File jar dalla guerra e rimontare sul lato server. Nel mio caso, questo taglia un WAR da 60MB fino a 250k che consente un'implementazione davvero rapida.

Il comando <exclude name="**/lib/*.jar"/> è quello che esclude del vaso (vedi ultima frammento di codice per ANT build)

Sul lato server, è abbastanza facile da montare un WAR completamente popolato dalla guerra rifilato:

  1. decomprimere/esplodere WAR rifilato che è stato creato dallo script ANT sotto
  2. copiare i file jar repository server nel esploso WEB-INF/lib
  3. zip è tutto in su in una nuova (grande) WAR.
  4. distribuire come al solito.

Ad esempio:

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

Forse non è la soluzione più elegante, ma consente di risparmiare tempo sul frequente distribuzione di grandi guerra. Mi piacerebbe essere in grado di farlo con Maven, quindi se qualcuno ha dei suggerimenti, per favore fatemelo sapere.

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

Io uso rsync a copiare il mio .war dalla mia macchina locale alla produzione. Di solito fornisce una grande velocità, circa 8-10 volte.

Un'altra opzione è utilizzare git per memorizzare i file .war. Quando si git push un nuovo .war, vengono trasferite solo le differenze. Anche una grande accelerazione. Alcune persone dicono che git non è progettato per archiviare file di grandi dimensioni, diventa lento e non funziona molto bene. In effetti sì, il pronti contro termine crescerà molto, ma in alcuni casi potrebbe essere una buona opzione.

Alcuni numeri: Il mio .war è di circa 50 MB e quando distribuisco una nuova versione, copia solo circa ~ 4 MB anziché caricare una nuova guerra completa. Entrambi con git e rsync.

UPDATE: Il problema che ho incontrato è il repo git non può essere clonato dopo che ha diverse versioni .war perché ci vorrà per sempre per creare tutti i delta e li trasmette al cliente.

Ho modificato la strategia caricando i file .war nella casella personale. Dropbox usa anche il tipo di rsync e copia solo i delta. Dal server wget il .war e ri-replicare l'app. Spero che questo ti aiuti.

+0

'rsync' è incredibilmente veloce! Solo pochi secondi invece di 5-7 minuti per la mia app. Il debug è veloce sulla macchina locale. Molte grazie! –

Problemi correlati