使用构建部署到生产的最简单方法

时间:2012-02-14 15:20:43

标签: tomcat deployment maven

我必须承认,在多年生活在怪异的debuild / ant / makefile嵌合构造的世界中,我对maven世界不熟悉。我还没有那种帮助经验丰富的开发人员选择正确决定的感觉,看起来maven中有很多不同的方式。

所以,我有一个包含web-app的简单项目。 我基本上想要跟随:

  • 部署到开发Tomcat(我正在使用tomcat:deploy),然后什么都不做。
  • 部署到生产Tomcat,但部署之前更新git repo,添加标记提交和升级构建版本。

为区分开发和制作,我创建了个人资料devprod。默认情况下会激活dev个人资料。当我想将某些内容部署到生产环境时,我只需输入mvn -P prod tomcat:deploy

即可

我读过有关发布插件以及buildnumber插件的内容。 但我只是不确定我是否正确行事。

所以,问题是 - 解决我正在询问的任务的最简单,自足和“少年”方式是什么。

6 个答案:

答案 0 :(得分:22)

Shabunk,正如我所评论的那样,Maven正在以最好的方式推动你做你想做的事情,继承了多年的开发经验。

我会解释我会做什么(以及我自己真正做的)。

所以你正确使用Maven Release Plugin,再加上另一个(例如货物) 你正在尝试做两件不同的事情:

  • 识别唯一版本,即标记它,并为新版本更新pom
  • 部署您的应用(无论是哪种环境)

Maven Release Plugin

考虑一下你自己的流程可能比其他开发团队习惯的更轻松。我的意思是在大型团队中进行单元测试和生产部署之间有更多的步骤(Q& A,用户接受,非回归支持)。您似乎可以创建一个链接标记和生产部署的快捷方式。 如果您想在不同的环境(集成,用户接受,性能,preprod等)上部署您的Web应用程序,您必须识别您的版本并且必须能够再次构建它(确定和"可重复的" )。

maven-release-plugin的目的是什么。它可以帮助您验证源代码是否干净(源代码管理下的所有文件,无需修改),可以编译并通过所有测试阶段。然后,它处理pom版本和标记,并通过存储它以便以后在Maven企业存储库中使用来完成。

您需要设置许多配置(ditributionManagement,SCM,maven插件发布配置)。但是一旦它到位,在一个简单的命令行中释放版本:

mvn release:prepare release:perform

如果你想要一些例子,我可以给你一些。

<scm>
    <!-- Base URL repository -->
    <url>scm:svn:http://svn.myorg.corp/svn/repository/</url>
    <!-- Developper URL (from trunk or branche) -->
        <developerConnection>scm:svn:http://svn.myorg.corp/svn/repository/trunk/project1</developerConnection>
  <connection>scm:svn:http://svn.myorg.corp/svn/repository/trunk/project1</connection>


</scm>
<build>
    <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-scm-plugin</artifactId>
                <version>1.6</version>
                <configuration>
            <username>${from.settings.xml.user}</username>
            <password>${from.settings.xml.password}</password>
                </configuration>
    </plugin>

    <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-release-plugin</artifactId>
                <version>2.2.2</version>
                <configuration>
                <tagBase>http://svn.myorg.corp/svn/repository/tags/</tagBase>
            <scmCommentPrefix>[DEV#SCM]</scmCommentPrefix>
        </configuration>
    </plugin>
</plugins>
    [...]
</build>
<distributionManagement>
    <repository>
        <id>enterprise_repo</id>
        <name>Enteprise Repository on Artifactory - Stable versions</name>      <url>http://repo.corp:8080/artifactory/prj-xxx-releases</url>
    </repository>
    <snapshotRepository>
        <id>enterprise_repo</id>
        <name>Enteprise Repository on Artifactory - DEV versions</name>
        <url>http://repo.corp:8080/artifactory/prj-xxx-snapshots</url>
    </snapshotRepository>
    <site>
        <id>corporate_site</id>
        <name>Corporate public site</name>
        <!-- must add wagon plugin that support this protocol -->
        <url>ftp://...</url>

    </site>
</distributionManagement>

<强> Deployement

再次,您可能需要多个环境来测试您的应用。 有许多插件可以让你发送和部署你的战争:一般货物插件,或更具体的tomcat-plugin,glassfish-plugin,...插件让你无法做你想做的事。然后,可以通过多种方式执行配置。

Full Maven方式: 与Maven完全集成的方法是使用Profile和Filters。正如您所知,简档描述了适当性和行为。过滤器是一种.properties,它将一组变量分组,用于将xml配置文件中的模式替换为war(例如,db connection)。它不是我使用的那个,因为我发现它不如外化文件灵活。但无论如何

Maven及其生态系统: 我喜欢的方式是使用Maven和Jenkins(或Continous Integration工具)构建我的应用程序。这就是为什么我同意Aaron说他必须知道你工具的局限性。使用Jenkins,我每小时/每天运行我的应用程序对抗单元测试,生成Q&amp; A报告,文档,...我有一个发布版本,帮助我生成我想要的所有内容(给我的测试团队或我的客户) ),我为我的工作提供了一些信息,以便将它部署到不同的环境中(使用maven配置文件或jenkins内置配置)。

它对我来说真的很好,而且我很确定这是正确的做法。

[编辑]


<强> 部署

再一次,部署意味着生命周期的不同阶段。

本地/开发环境

我从不使用tomcat:直到现在才部署,但这只是因为我更喜欢使用jetty作为轻型网络容器(并与maven集成)。但我非常确定每一种配置都符合您的需求。

持续集成环境 在一个连续的集成环境中,我通常直接用Jenkins复制战争(在所需的机器上输出* .war)。我的方式取决于很多事情:

  • 如果CI软件位于与您的应用服务器(Tomcat,Jboss,Weblogic,Glassfish,...)相同(物理|虚拟)服务器上,或远程服务器=&gt;复制时间将超过服务器刷新时间,并将产生不安全的部署(通常是损坏的存档)
  • 如果服务器支持热重新加载(针对Tomcat的web-apps中的爆炸性战争)或者至少知道文件系统修改(JBoss / deploy中的完整战争)
  • 如果您之前需要停止服务器,......

大部分时间,它都是一个简单的副本。如果我不能,我会使用一些集成的maven插件(比如jahia:为着名的CMS部署插件:www.jahia.com),或者只使用货物插件:http://cargo.codehaus.org/Maven2+plugin。我没有任何例子,但在互联网上找到一些很容易,因为这种配置经常被推荐。

Q&amp; A /接受/制作环境

对于那些经常(就我在工作中看到的那样)处理服务水平协议的环境,我们(我或管理团队)编写了一些特定的脚本。我确信你会变得沮丧,但正如我所提到的,我并不依赖Maven来做任何事情,尤其是部署。 恕我直言,这是这个工具的一个限制。您可以依赖货物插件或特定货物插件,但可以发布一个版本,或者与实际部署建立一个不匹配(按时间顺序)。更重要的是,我没有找到任何允许我轻松部署在多个实例上的插件......甚至值得你按特定顺序关闭实例(SLA&#39需要)。 也就是说,我没有提到外部属性,SQL脚本或其他任何东西。它们是依赖专用工具的其他理由。

因此,通常,我们编写了自己的ant / sell脚本。如果其他人有更好的解决方案,我明显感兴趣!

我希望我足够清楚。

问候。

答案 1 :(得分:4)

原始问题要求使用Maven进行生产部署的“最佳实践”。我希望获得不止一个“最佳实践”并提供赏金以查看不同的解决方案并从中学习。我不在乎它们是纯粹的maven解决方案还是使用不同的工具。

与这个主题并行,我也做了一些研究,并希望在这里发布我所看到的不同方法。我试过1)和3),他们是纯粹的专家,无论亚伦在说什么,他们也在努力。

在我目前的项目中,我有一个开发环境,一个测试环境,一个临时环境和一个生产环境。从我的maven pom开始,我想使用开发环境并仅部署到测试环境。我在maven pom中看到了以下方法:

  1. 具有过滤属性的配置文件
    使用此方法时,必须针对不同环境重建可交付物(war文件)。这迫使我提供赏金,因为我不喜欢这样。
  2. 个人资料Maven WAR overlaysassembly plugin
    这也为不同平台产生了不同的人工制品。但是,不是重建war文件,它将被解压缩/修补/重新打包(用于战争覆盖)或构建和打包不同的设置(程序集插件)。我也不喜欢这个解决方案。
  3. 没有配置文件的部署插件(例如Cargo plugin) 使用安装指定完整构建,并且还包括执行远程部署但未将其连接到任何阶段的货物插件。所以我总是使用开发环境但是当我明确地调用货物插件时,它会将战争从存储库部署到容器(测试环境)。我甚至可以使用配置文件来区分不同的容器,仅用于通过货物进行部署。
  4. 在所有解决方案中,我使用集成测试(surefire插件),版本插件和发布插件来构建战争。对于部署,我按照https://stackoverflow.com/a/1151870/734687的参数实现了第3号方法(这个帖子表达了我非常喜欢的内容)。

    由于应用程序必须在所有环境中保持不变,因此必须区分运行时的不同设置,这可能非常复杂。我们的运营团队希望在容器外部为每个应用程序设置设置,因此我支持环境var,它指向正确的目录但是可选的。如果没有设置,那么我使用战争中的开发设置。在这里查看Spring示例:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreResourceNotFound" value="true"/>
        <property name="locations">
            <list>
                <value>classpath:META-INF/spring/*.properties</value>
                <value>file:///${picservice.configdir:-}/*.properties</value>
            </list>
        </property>
    </bean>
    

    META-INF / spring目录中的属性始终加载。另外,我整合了文件系统中的属性,这些属性可以覆盖上面的属性。如果没有找到属性,则不会触发异常,因为我设置了ignoreResourceNotFound。如果设置了属性picservice.configdir,它会将我定向到一个目录,如果不是,我提供了:的默认值。 -表示我想要没有当前目录的值。

    对于日志记录,我有一个类似的解决方案。您可以在以下链接中找到有关使用Spring处理属性文件的非常有趣的文章:

    我找到了有关此主题的有趣演示文稿,请参阅Automated Deployment with Maven and friends

答案 2 :(得分:2)

  

更新git repo,添加标记提交并升级构建版本。

-

  

我读过有关发布插件以及buildnumber插件的内容。   但我只是不确定我是否走得正确。

是的,建议使用发布插件。如果你想在某些文档中使用buildnumber,你可以使用buildnumber插件,例如CHANGES.txt

答案 3 :(得分:2)

我认为完成您指定内容的最简单方法(如果我理解的话)是按如下方式配置Maven Release Plugin

<!-- path: project/build/pluginManagement/plugins -->
<plugin>
  <artifactId>maven-release-plugin</artifactId>
  <configuration>
    <releaseProfiles>prod</releaseProfiles>
    <goals>tomcat:deploy</goals> 
  </configuration>
</plugin>

对于开发部署,请按以下步骤继续:mvn tomcat:deploy -P dev(如果dev默认处于活动状态,则删除-P dev参数。

当按Maven Release Plugin期望的两个步骤释放时,继续:

mvn release:prepare

此目标会根据需要增加版本和标记(and more)。请注意,您还需要通过在POM中配置此标记来指定Maven应该使用的SCM

<!-- path: project -->
<scm>
  <connection>scm:git:ssh://yourrepo.url</connection>
</scm>

SCM plugin支持wide variety of SCM managers and protocols(您可能对git:httpgit:https感兴趣。)

然后

mvn release:perform

这将使用配置文件prod,只需运行目标tomcat:deploy,就像您配置的那样。

我希望这就是你所需要的。问候。

答案 4 :(得分:1)

当您遇到常见情况的例外时,Mavenized解决方案不会使用Maven。 Maven是关于常见病例的。异常在其他地方处理,这意味着POM(应该)从不包含任何意外。

由于您需要自定义部署过程,因此请编写一个shell脚本或Ant build.xml,它执行必要的步骤并在此过程中使用Maven进行部署。

这样,每个工具都可以做到最好。

[编辑] 请注意所有的挫折者:除非你有争执,否则你的下来投票就没有任何意义。 Maven是一个工具。像所有工具一样,它有限制。 Maven的核心理念是避免例外。 Ant是关于角落的情况,Maven是关于主流的。从“What is Maven?”页面:

  
      
  • 简化构建过程
  •   
  • 提供统一构建系统
  •   

(我的重点)所以是的,Maven不是最好的解决方案。如果标准发布流程适合您,请使用release plugin

但如果没有,那就去别处寻找而不是陷入“everything looks like a nail心灵陷阱”。

主要的个人开发步骤之一是了解您自己的限制以及您使用的工具的限制。当工具不适合工作时,请尝试使用其他工具,而不是试图扭曲现实。你的生活会更快乐。

答案 5 :(得分:0)

也许是用另一种工具来解决你的问题,它很简单,你可以制作自定义流程

Phing website

相关问题