在开发过程中,我经常需要将一个大的war文件(约45 MB)部署到远程测试服务器上,通常我会使用scp将文件复制到服务器上。
WEB-INF/lib文件夹占据了war文件的最大部分,其中包含了所有必要的库(spring、apache-cxf、hibernate等)。
现在,我正在寻找一种快速且简单的方法来重新部署只更改过的文件。
我如何确定web应用程序真正需要哪些包,因为spring和apache-cxf附带了许多库,我确信我不需要全部。
在开发过程中,我经常需要将一个大的war文件(约45 MB)部署到远程测试服务器上,通常我会使用scp将文件复制到服务器上。
WEB-INF/lib文件夹占据了war文件的最大部分,其中包含了所有必要的库(spring、apache-cxf、hibernate等)。
现在,我正在寻找一种快速且简单的方法来重新部署只更改过的文件。
我如何确定web应用程序真正需要哪些包,因为spring和apache-cxf附带了许多库,我确信我不需要全部。
.war
文件时,Tomcat首先会将该文件解压缩到其webapps
目录中,子目录与您的.war
同名。.class
文件、.jar
文件、配置文件以及最终进入您的.war
的任何其他文件。您可以轻松地确定受到您更改影响的一小部分文件。找出来后,使用脚本或ant
任务或其他方法,将这些少量文件直接复制到服务器上的webapps/yourapp
目录中。WEB-INF/web.xml
。因此,让您的部署过程touch
该文件或以其他方式更新它,使其具有新的时间戳,scp
它也是(最好作为您更新的文件的最后一个),然后您就可以快速轻松地重新加载了。<exclude name="**/lib/*.jar"/>
命令用于排除jar文件(请参见ANT构建的最后一个代码片段)。unzip ../myapp.trimmed.war
mkdir WEB-INF/lib
cp ../war_lib_repository/* WEB-INF/lib
zip -r ../myapp.war .
<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>
在Rori Stumpf的答案基础上进行改进,这是一个针对“瘦身”操作的Gradle任务。
war {
archiveName "v1.war"
}
task createThinWar(type: Copy) {
dependsOn 'war'
def tmpFolder = "${buildDir}/tmp/thin"
def outputDir = "${buildDir}/libs"
// Extract the war (zip) contents
from zipTree("${outputDir}/v1.war")
into "${tmpFolder}/v1"
doLast {
// Extracting the war third party libraries to a separate dir
ant.move(file: "${tmpFolder}/v1/WEB-INF/lib", tofile: "${tmpFolder}/v1-libs")
// Zip the third party libraries dir
ant.zip(destfile: "${outputDir}/v1-libs.zip") {
fileset(dir: "${tmpFolder}/v1-libs")
}
// Finally zip the thinned war back
ant.zip(destfile: "${outputDir}/v1-thin.war") {
fileset(dir: "${tmpFolder}/v1")
}
}
}
rsync
将本地机器上的.war
复制到生产环境。通常可以提供大量加速,约为8-10倍。git
存储.war
文件。当你git push
一个新的.war
时,只有差异会被传输。这也是一个很大的加速。有些人说git不适合存储大文件,它会变慢并且不能很好地工作。事实上,是的,仓库会增长很多,但在某些情况下,这可能是一个很好的选择。.war
大约为50MB,当我部署新版本时,它只复制了约4MB而不是上传完全新的war。无论是使用git
还是rsync
都可以达到这个效果。
更新: 我遇到的问题是,当Git仓库有几个.war
版本时,它将永远无法克隆,因为需要创建所有增量并将其传输到客户端。.war
文件到 Dropbox。Dropbox 也使用了一种类似于 rsync
的方法,只复制增量。从服务器上,我使用 wget 命令下载 .war
文件并重新部署应用程序。希望这可以帮到你。我认为没有更快的方法来重新部署WAR文件中的更改。
如果您以展开的方式部署,您可以查看哪些文件时间戳已更改并相应地采取行动,但您将不得不编写代码来执行此操作。
我不知道OSGi是否能在这里提供帮助。这将允许您将问题分成更独立和可交换的模块。
只是好奇:
rsync
速度非常快!只需要几秒钟,而不是我的应用程序需要的 5-7 分钟。调试速度与本地机器一样快。非常感谢! - no id