将大型* .war部署到tomcat的最佳方法

时间:2010-07-06 09:34:00

标签: deployment tomcat war

在开发过程中,我经常需要将一个大型war文件(~45 MB)部署到远程测试服务器,通常我用scp将文件复制到服务器。

WEB-INF / lib文件夹构成war文件的最大部分,其中包含所有必需的库(spring,apache-cxf,hibernate,...)。

现在我正在寻找一种快速简便的方法来重新部署我修改过的文件。

我怎样才能确定webapp真正需要哪些软件包,因为spring和apache-cxf附带了很多库,我相信我并不需要所有这些软件包。

5 个答案:

答案 0 :(得分:6)

部署.war时,Tomcat所做的第一件事就是将该文件解压缩到webapps目录中,并在与.war同名的子目录中。

在开发过程中,您显然可以访问.class个文件,.jar文件,配置文件以及最终进入.war的其他内容。您可以轻松地建立受更改影响的一小部分文件。想出来,然后使用脚本或ant任务或其他任务将这些少量文件直接复制到服务器上的webapps/yourapp目录中。

要查看更改生效,您需要重新启动应用程序。如果Tomcat处于开发模式,强制重新加载(当然还有重启)的一种简单方法是更新WEB-INF/web.xml。因此,让您的部署过程touch以一种方式对文件进行更新或更新,以便为其提供新的时间戳,scp也可以(最好是您更新的最后一个文件)并且您应该拥有快速轻松的重装。

答案 1 :(得分:2)

我所做的是从WAR中排除WEB-INF / lib / * .jar文件并在服务器端重新组装。在我的情况下,它将60MB WAR减少到250k,这样可以实现快速部署。

<exclude name="**/lib/*.jar"/>命令排除了jar的内容(请参阅ANT版本的最后一个代码段)

在服务器端,从修剪过的WAR组装完全填充的WAR非常容易:

  1. 解压缩/爆炸由下面的ANT脚本创建的裁剪WAR
  2. 将服务器存储库jar文件复制到展开的WEB-INF / lib
  3. zip全部用于新的(大型)WAR。
  4. 像往常一样部署。
  5. 例如:

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

    也许不是最优雅的解决方案,但它可以节省频繁部署大型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>           
    

答案 2 :(得分:1)

我使用rsync将我的.war从本地计算机复制到生产环境。它通常提供大幅加速,大约8-10倍。

另一种选择是使用git来存储.war个文件。当您git push.war时,只会转移差异。也是一个很大的加速。有些人说git不是为存储大文件而设计的,它变慢而且效果不好。实际上是的,回购将会增长很多,但在某些情况下它可能是一个不错的选择。

有些数字:我的.war约为50MB,当我部署新版本时,它只复制约4MB而不是上传完整的新战争。 gitrsync

更新:我遇到的问题是git repo在有多个.war版本之后无法克隆,因为创建所有增量并将它们传输到客户端需要永远

我通过将.war文件上传到dropbox来更改策略。 Dropbox也使用rsync种,只复制增量。从服务器我获取.war并重新部署应用程序。希望这会有所帮助。

答案 3 :(得分:0)

我认为没有更快的方法可以仅将更改重新部署到WAR文件中。

如果以爆炸方式部署,您可以看到哪些文件时间戳已更改并采取相应措施,但您必须编写代码才能执行此操作。

我不知道OSGi是否可以在这里提供帮助。这样您就可以将问题划分为更独立且可交换的模块。

好奇:

  1. 现在需要多长时间?
  2. 您是否使用持续集成来构建和部署?

答案 4 :(得分:0)

改进Rori Stumpf答案,这是“稀疏&#39;

的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")
        }
    }
}

这将生成v1-thin.war(权重小于1mb)和libs zip。

将瘦战部署到服务器(并在那里重建lib),并在修改版本/添加库时部署libs zip。