2010-07-06 3 views
10

Во время разработки мне часто приходится развертывать большой военный файл (~ 45 МБ) на удаленном тестовом сервере, обычно я копирую файл с scp на сервер.Лучший способ развернуть большой * .war до tomcat

Папка WEB-INF/lib составляет самую большую часть военного файла, который включает в себя все необходимые библиотеки (spring, apache-cxf, hibernate, ...).

Теперь я ищу быстрый и простой способ переотложить только измененные файлы.

И как я могу определить, какие пакеты действительно нужны webapp, потому что весна и apache-cxf поставляется с большим количеством libs, я уверен, что мне не нужны все они.

ответ

5

При развертывании .war, первое, что Tomcat делает распаковать этот файл в свой каталог webapps, в подкаталоге с тем же именем, как .war.

Во время разработки у вас, очевидно, есть доступ к вашим файлам .class, файлам .jar, файлам конфигурации и всем остальным, что в конечном итоге входит в ваш .war. Вы можете легко установить небольшое подмножество файлов, на которые повлияли ваши изменения. Извлеките это, а затем используйте скрипт или задачу ant или что угодно, чтобы скопировать только эту небольшую часть файлов прямо в каталог webapps/yourapp на сервере.

Чтобы изменения вступили в силу, вам нужно будет заново запустить приложение. Если Tomcat находится в режиме разработки, один простой способ принудительно перезагрузить (и, конечно же, перезапустить) - это обновить WEB-INF/web.xml. Так что приложите свой процесс развертывания touch к этому файлу или иным образом обновите его таким образом, чтобы дать ему новую временную метку scp, которая слишком (желательно как последний из файлов, которые вы обновляете), и вам нужно быстро и просто перезагрузить.

0

Я не думаю, что существует более быстрый способ переделать только изменения в файл WAR.

Если вы развертываете в разобранном виде, вы можете увидеть, какие временные метки файлов были изменены и действуют соответственно, но вам придется писать код, чтобы сделать это.

Я не знаю, поможет ли OSGi помощь здесь. Это позволит вам разделить вашу проблему на модули, которые являются более независимыми и свопированными.

Просто любопытно:

  1. Сколько времени это займет сейчас?
  2. Вы используете непрерывную интеграцию для сборки и развертывания?
+0

Самой большой проблемой является время загрузки на удаленный сервер, развертывание которого выполняется автоматически и чисто. Я могу только проверить отверстие webapp на удаленном сервере, из-за hudge и сложной подсистемы, на которой создается webapp. – Alex

2

То, что я делаю, исключает файлы WAR-INF/lib/*. Jar из WAR и собирает их со стороны сервера. В моем случае это уменьшает 60MB WAR до 250 тысяч, что позволяет очень быстро развертывать.

Команда <exclude name="**/lib/*.jar"/> что исключает баночка (см последний фрагмент кода для ANT сборки)

На стороне сервера, это довольно легко собрать полностью заселен WAR из обрезанного WAR:

  1. unzip/explode обрезанная WAR, которая была создана скриптом ANT ниже
  2. копировать файлы хранилища репозитория сервера в разложенные WEB-INF/lib
  3. zip все в новую (большую) WAR.
  4. развертывание как обычно.

Например:

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

Может быть, не самое элегантное решение, но это экономит время на частые развертывания больших войны. Я хотел бы иметь возможность сделать это с Maven, поэтому, если у кого-то есть предложения, пожалуйста, дайте мне знать.

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

Я использую rsync скопировать мой .war из моей локальной машине производства. Обычно он обеспечивает большую скорость, примерно в 8-10 раз.

Другой вариант - использовать git для хранения файлов .war. Когда вы git push новый .war, передаются только отличия. Также большая скорость. Некоторые говорят, что git не предназначен для хранения больших файлов, он работает медленно и не работает очень хорошо. На самом деле да, репо будет расти много, но в некоторых случаях это может быть хорошим вариантом.

Некоторые номера: Мой .war составляет около 50 МБ, и когда я развожу новую версию, она копирует только ~ 4 МБ, а не загружает полную новую войну. Как с git, так и с rsync.

UPDATE: Проблемы я столкнулся это мерзавец репо не может быть клонирован после того, как несколько .war версий, потому что это будет длиться вечно, чтобы создать все дельты и передавать их клиенту.

Я изменил стратегию, загрузив файлы .war в Dropbox. Dropbox также использует вид rsync и только копирует дельта. С сервера я запустил .war и повторно разместил приложение. Надеюсь это поможет.

+0

'rsync' невероятно быстро! Всего несколько секунд вместо 5-7 минут для моего приложения. Отладка выполняется так же быстро на локальной машине. Большое спасибо! –