Maven 部署到多个 Tomcat 服务器

Posted

技术标签:

【中文标题】Maven 部署到多个 Tomcat 服务器【英文标题】:Maven Deploy To Multiple Tomcat Servers 【发布时间】:2010-10-18 10:50:10 【问题描述】:

使用可以编写的 maven 将战争部署到多个 tomcat 服务器的最小示例是什么?

我尝试了以下 URL 并询问了邮件列表,但没有提出任何简短且简单有效的内容。

http://www.nabble.com/Deploying-to-Multiple-Servers-at-Once-td21592419.html

示例应该在某处定义示例中的服务器(带有示例用户名/密码)

【问题讨论】:

【参考方案1】:

Markus Lux 的想法也可以应用于 Maven2 解决方案,并带有配置文件管理:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.cargo</groupId>
            <artifactId>cargo-maven2-plugin</artifactId>
        </plugin>
    </plugins>
    ...
</build>
<profiles>
    <profile>
        <id>env-foo1</id>
        <!-- Activated when -Denv=foo1 is given as parameter. -->
        <activation>
            <property>
                <name>env</name>
                <value>foo1</value>
            </property>
        </activation>
        <properties>
            <deploy.env>xxx</deploy.env>
            <tomcat.manager>http://foo1/manager</tomcat.manager>
            <tomcat.manager.username>foo</tomcat.manager.username>
            <tomcat.manager.password>bar</tomcat.manager.password>
        </properties>
    </profile> 
    <profile>
        <id>env-foo2</id>
        <!-- Activated when -Denv=foo2 is given as parameter. -->
        <activation>
            <property>
                <name>env</name>
                <value>foo2</value>
            </property>
        </activation>
        <properties>
            <deploy.env>dev</deploy.env>
            <tomcat.manager>http://foo2/manager</tomcat.manager>
            <tomcat.manager.username>foo</tomcat.manager.username>
            <tomcat.manager.password>bar</tomcat.manager.password>
        </properties>
    </profile>
    ... 
</profiles>    

然后,您只需要运行 X 次 mvn 命令,并使用适当的参数 (-Denv=foo1, -Denv=foo2 em>,...)


除此之外,您还可以使用Hudson 持续集成服务器的矩阵功能来增强此解决方案。我对这个功能做了一个简短的解释here。

基本上,您只需在 Hudson 中定义一个“正常”的 Maven2 作业,使用 Matrix 功能,您可以要求 Hudson 多次运行该作业,每个环境运行一次。换句话说,您创建了 Hudson 作业,然后使用 env 参数的所有可能值定义“环境轴”:

foo1 foo2 foo3 ...

Hudson 然后将使用 mvn 命令和参数 -Denv=foo1 构建应用程序。一旦构建完成,它将构建相同的应用程序,但使用参数-Denv=foo2,等等……

这样,Hudson 将在每个环境中部署您的应用程序...

希望我的解决方案能帮助您实现目标...

【讨论】:

天哪,这可能非常有用,因为 Hudson 正是我在...中使用它的目标。 有趣的是,这与我给出的链接所暗示的相似,但并不十分清楚。迫不及待想尝试一下。 有没有办法做到这一点而不必调用 maven X 次?在我看来,再次构建只是为了部署非常耗时,而且如果在这些构建期间对代码进行了新的更改,它可能会导致跨集群的部署不一致【参考方案2】:

关于使用多个配置文件,生命周期似乎重复了某些步骤 - 例如。使用由变量激活的配置文件时,测试次数增加了一倍。我们发现使用 catalina-ant 库更有效;)而且它更“最小”。使用“executions”元素将“run”目标附加到生命周期阶段以简化它,或者在 package 之后运行:mvn package antrun:run

您可以更花哨地使用 ant-contrib 库,并创建一个包含服务器列表的 for 循环,但这里是 2 个硬编码服务器 url 的静态配置。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.6</version>
    <configuration>
        <target>
            <taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"/>
            <deploy url="http://tc-app-01:8080/manager" username="manager" password="pass"
                    path="/app-path" war="file:$project.build.directory/$project.build.finalName.$project.packaging" update="true"/>

            <deploy url="http://tc-app-02:8080/manager" username="manager" password="pass"
                    path="/app-path" war="file:$project.build.directory/$project.build.finalName.$project.packaging" update="true"/>
        </target>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>tomcat</groupId>
            <artifactId>catalina-ant</artifactId>
            <version>6.0.29</version>
        </dependency>
    </dependencies>
</plugin>

上面使用的catalina-ant的具体版本是手动部署到我们的分布式maven仓库的,可以在tomcat发行版的lib目录下找到。

【讨论】:

【参考方案3】:

这是对一个老问题的较晚回答,但我很确定人们会对它感兴趣。我刚刚实现了使用 maven 和 ant 任务运行多个部署。秘诀是使用宏定义(或 2,因为我在码头热部署我的应用程序并需要传输战争和 xml 文件)并使用 ant 属性文件:

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <phase>install</phase>
            <configuration>
                <tasks>
                    <taskdef name="scp"
                        classname="org.apache.tools.ant.taskdefs.optional.ssh.Scp"
                        classpath="/usr/local/java/ant/lib/ant-jsch.jar:/usr/local/java/ant/lib/jsch-0.1.45.jar" />
                    <macrodef name="deploy">
                        <attribute name="server" default="NOT SET" />
                        <attribute name="file" default="NOT SET" />
                        <attribute name="todir" default="NOT SET" />
                        <attribute name="port" default="NOT SET" />
                        <attribute name="passphrase" default="NOT SET" />
                        <attribute name="keyfile" default="NOT SET" />
                        <sequential>
                            <echo message="Deploying to @server" />
                            <echo message="Deploying @file to @todir" />
                            <scp
                                file="@file" todir="@todir"
                                port="@port" passphrase="@passphrase"
                                keyfile="@keyfile" />
                        </sequential>
                    </macrodef>
                    <macrodef name="deploy-app">
                        <attribute name="config" default="NOT SET" />
                        <sequential>
                            <property file="deploy.properties"/>
                            <echo message="Deploying to @config" />
                            <deploy server="$@config.jetty.server.host"
                                    file="$project.build.directory/$project.build.finalName.$project.packaging"
                                    todir="$@config.jetty.server.user@$@config.jetty.server.host:$@config.jetty.server.baseDir/$@config.jetty.server.webappsDir"
                                    port="$@config.jetty.server.port"
                                    passphrase="$@config.jetty.server.passphrase"
                                    keyfile="/home/steff/.ssh/id_rsa"/>
                            <deploy server="$@config.jetty.server.host"
                                    file="$project.build.finalName.xml"
                                    todir="$@config.jetty.server.user@$@config.jetty.server.host:$@config.jetty.server.baseDir/$@config.jetty.server.contextDir"
                                    port="$@config.jetty.server.port"
                                    passphrase="$@config.jetty.server.passphrase"
                                    keyfile="/home/steff/.ssh/id_rsa"/>                                     
                        </sequential>
                    </macrodef>                             
                    <deploy-app config="home"/>     
                    <deploy-app config="wap"/>
                </tasks>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

那么你的属性文件需要是这样的:

home.jetty.server.user=
home.jetty.server.port=
home.jetty.server.host=
home.jetty.server.baseDir=
home.jetty.server.webappsDir=
home.jetty.server.contextDir=
home.jetty.server.passphrase=
wap.jetty.server.user=
wap.jetty.server.port=
wap.jetty.server.host=
wap.jetty.server.baseDir=
wap.jetty.server.webappsDir=
wap.jetty.server.contextDir=
wap.jetty.server.passphrase=

etc...

使用的每个服务器配置的选项块
<deploy-app config="<config>"/>

诀窍是在 ant 中使用 @ 作为属性评估 $ 的优先级的宏定义属性。

【讨论】:

【参考方案4】:

也许“最小”的解决方案根本就不是最小的。如果您在 Maven 本身中执行此操作时遇到问题,请尝试使用 ant:创建两个不同的部署任务(每个服务器一个)和另一个将它们作为依赖项的任务。有几个示例如何使用 ant 部署到 tomcat 服务器。 Just google them。 完成此操作后,您需要将新的 ant 任务集成到 maven 中,使用 antrun 插件一点也不难。

【讨论】:

真的,我希望有一个例子。【参考方案5】:

此答案适用于 Jetty,适用于稍微不同的情况,但无论如何您可能会发现它很有用。

在之前的项目中,我们使用了 Jetty,因此我编写了一个简单的 Jetty 部署程序模块,该模块会定期扫描 maven 存储库并在新工件可用时立即下载和部署。这在一个小型暂存和开发机器集群上运行良好。

您可以在 Polar Rose Jetty Maven Deployer 项目的 Google 代码中找到代码。

请注意,我们仅对开发和登台服务器执行此操作。在我看来,生产应用程序永远不应该自动升级。

【讨论】:

以上是关于Maven 部署到多个 Tomcat 服务器的主要内容,如果未能解决你的问题,请参考以下文章

maven工程,如何部署到tomcat的位置?

eclipse下创建maven项目并部署到tomcat服务器(转)

Maven自动部署Web项目到Tomcat服务器

maven自动部署到远程tomcat教程

用Maven部署war包到远程Tomcat服务器

Maven部署war项目到远程Tomcat服务器