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

eagi6jfj  于 2022-10-26  发布在  Maven
关注(0)|答案(6)|浏览(249)

我必须承认,在经历了多年可怕的deBuild/ant/Makefile嵌合结构的世界后,我对maven世界还很陌生。我只是还没有那种帮助经验丰富的开发人员选择正确决策的感觉,而且看起来在Maven中有很多不同的方法。
所以,我有一个简单的项目包含的网络应用程序。我想基本上遵循以下原则:

  • 部署到开发Tomcat(我使用的是Tomcat:Deploy),然后什么都不做。
  • 部署到生产Tomcat,但部署前更新git repo,添加标签提交,升级Build版本。

为了区分开发和生产,我创建了配置文件devprod。默认情况下,dev配置文件处于激活状态。当我想要将某些东西部署到生产环境中时,我只需输入mvn -P prod tomcat:deploy
我读过关于发布插件的文章,也读过关于构建号插件的文章。但我只是不确定我走的路对不对。
所以,问题是--解决我所问的任务的最简洁、最独立、最“专业”的方法是什么?

lymgl2op

lymgl2op1#

Shabunk,正如我所评论的那样,Maven从多年的开发人员经验中继承下来,正在推动您以最好的方式做您想做的事情。
我会解释我会做什么(以及我自己真正会做什么)。
因此,您使用Maven发布插件是正确的,外加另一个插件(例如Cargo),您正在尝试做两件不同的事情:

  • 识别唯一版本,这意味着对其进行标记,并为新版本更新POM
  • 部署您的应用程序(无论是哪种环境)
  • Maven发布插件*

考虑到您自己的流程可能比其他开发团队习惯的流程要轻松一些。我的意思是,在更大的团队中,单元测试和生产部署之间有更多的步骤(Q&A、用户接受度、非回归Camain)。看起来你是一条连接标签和生产部署的捷径。如果您想在不同的环境(集成、用户接受、性能、预生产等)上部署您的Web应用程序,您必须确定您的版本,并且必须能够重新构建它(当然并且是“可重复的”)。
这就是maven-Release-plugin的目的。它帮助你验证你的源代码是干净的(所有受源代码控制的文件,没有修改),可以编译并通过所有测试阶段。然后,它处理POM版本和标记,最后将其存储在您的Maven企业存储库中以备将来使用。
您有许多配置要设置(分发管理、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>
  • 部署*

同样,您可能要在多个环境中测试您的应用程序。有许多插件允许您发送和部署您的战争:通用货物插件,或更具体的Tomcat插件,GlassFish插件,...插件使您能够做您想做的事情。然后,可以通过多种方式执行配置。

  • Full Maven Way:*与Maven完全集成的方式是使用配置文件,可能还会使用过滤器。正如你似乎知道的那样,个人资料可以描述财产和行为。筛选器类似于将一组变量分组在一起,这些变量将用于将您的XML配置文件中的模式替换到WAR中(例如,数据库连接)。这不是我使用的方法,因为我发现它不如外部化文件灵活。但不要紧
  • Maven及其生态系统:*我更喜欢的方式是使用Maven和Jenkins(或Continous集成工具)构建我的应用程序。这就是为什么当Aaron说你必须知道你的工具的局限性时,我同意他的观点。使用Jenkins,我每天几个小时都在针对单元测试运行我的应用程序,生成问答报告、文档,……我有一个发布版本,可以帮助我生成我想要交付的所有内容(给我的测试团队或我的客户),我为我的工作提供一些信息,以便将其部署到不同的环境中(使用Maven配置文件或Jenkins内置配置)。

它对我来说真的很好,我非常确定这是正确的做法。
[编辑]

  • 部署*

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

本地/开发环境

在此之前,我从未使用过Tomcat:Deploy,但这只是因为我更喜欢使用Jetty作为轻量级Web容器(并与Maven很好地集成)。但我非常肯定,这里的每一种配置都能满足您的需求。

持续集成环境在持续集成环境中,我通常直接使用Jenkins复制WAR(在所需的机器上导出*.war)。我这样做的方式取决于很多事情:

  • 如果CI Soft与您的应用服务器(Tomcat、JBoss、WebLogic、GlassFish等)位于同一(物理|虚拟)服务器上,或位于远程服务器上=>复制时间将超过服务器刷新时间,并将产生不安全的部署(通常是损坏的归档)
  • 如果服务器支持热重新加载(Tomcat的Web应用程序中的爆炸性WAR)或至少知道文件系统修改(JBoss的完整WAR In/Deploy)
  • 如果您需要在此之前停止服务器,...

大多数时候,它都是一个简单的复制品。如果我做不到,我会使用一些集成的maven插件(比如著名的CMS:www.jahia.com的JAHIA:Deploy插件),或者只使用Cargo Plugin:http://cargo.codehaus.org/Maven2+plugin。我没有任何例子,但在网上很容易找到一些,因为这种配置经常被推荐。

问答/验收/生产环境

对于那些经常(就我在我的工作中所见)处理服务级别协议的环境,我们(我或管理团队)编写了一些特定的脚本。我相信您会大失所望,但正如我前面提到的,我并不是所有事情都依赖于Maven,尤其是在部署方面。我的天,这是这个工具的一个限制。您也许可以依赖Cargo插件,或者特定的插件,但是发布一个版本,或者构建一个与实际部署不匹配(按时间顺序)的插件。更重要的是,我没有找到任何可以让我轻松地在多个示例上部署的插件……甚至值得您按特定顺序关闭示例(SLA的需求)。也就是说,我没有提到外部属性、SQL脚本或其他任何东西。它们是依赖专用工具的额外理由。
因此,总的来说,我们编写了自己的ant/sell脚本。如果其他人有更好的解决方案,我显然很感兴趣!
我希望我说得够清楚了。
向你问好。

8fq7wneg

8fq7wneg2#

最初的问题是询问使用Maven进行生产部署的“最佳实践”。我希望得到不止一种“最佳实践”,并提出赏金,让我看到不同的解决方案,并从中学习。我不在乎它们是纯粹的maven解决方案,还是使用不同的工具。
与这条线索并行,我也做了一些研究,并想在这里张贴我看到的不同方法。我试过了1)和3),他们是纯粹的Maven,不管亚伦怎么说,他们也在工作。
在我目前的项目中,我有一个开发环境、一个测试环境、一个试运行环境和一个生产环境。在我的maven pom中,我希望使用开发环境,并且只部署到测试环境。我认为maven pom有以下几种方法:
1.具有过滤属性的配置文件
在使用这种方法时,必须针对不同的环境重新构建交付件(WAR文件)。这迫使我提出赏金,因为我不喜欢这样。
1.Maven WAR overlaysassembly plugin配置文件
这也为不同的平台生成了不同的人工制品。但不是重新构建WAR文件,而是将其解包/修补/重新打包(用于WAR覆盖),或者使用不同的设置(汇编插件)进行构建和打包。我也不喜欢这个解决方案。
1.部署插件(例如Cargo plugin)无配置文件
指定带有安装的完整构建,还包括执行远程部署但不将其连接到任何阶段的Cargo插件。所以我总是使用开发环境,但是当我显式地调用Cargo插件时,它会将WAR从存储库部署到容器(测试环境)。我甚至可以使用配置文件来区分不同的集装箱,仅用于通过货物进行部署。
在所有的解决方案中,我都使用集成测试(surefire插件)、版本插件和发布插件来构建WAR。对于部署,我在https://stackoverflow.com/a/1151870/734687(这篇文章表达了我也喜欢的内容)的参数之后实现了方法3。
由于应用程序必须在所有环境中不加更改地工作,因此您必须区分运行时的不同设置,这可能非常复杂。我们的运营团队希望容器外的每个应用程序都有设置,所以我支持一个环境变量,它将我指向正确的目录,但它是可选的。如果未设置任何内容,则使用WAR中的开发设置。请参阅此处的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

8fq7wneg

8fq7wneg3#

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

我读过关于发布插件的文章,也读过关于构建号插件的文章。但我只是不确定我走的路对不对。
是的,使用发布插件是推荐的方式。如果您想要某个文档(如CHANGES.txt)中的构建编号,您可以使用构建编号插件

eoigrqb6

eoigrqb64#

我认为完成您指定的任务的最简单方法(如果我理解得很好)是按如下方式配置Maven Release Plugin

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

对于dev部署,按照您的操作进行:mvn tomcat:deploy -P dev(如果默认情况下dev处于活动状态,则删除-P dev参数)。
发布时,如Maven Release Plugin所料,分两步进行:

mvn release:prepare

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

<!-- 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,与您配置的完全相同。
我希望这就是你需要的。向你问好。

9rygscc1

9rygscc15#

Mavenized化的解决方案是,当您对常见情况有例外时,不使用Maven。Maven完全是关于常见案例的。异常在其他地方处理,这意味着POM(应该)永远不会包含任何意外。
因为您需要一个定制的部署过程,所以编写一个外壳脚本或一个Ant build.xml来执行必要的步骤,并在该过程中使用Maven进行部署。
这样一来,每个工具都做了它能做得最好的事情。
从“What is Maven?”页面:

  • 使构建过程变得简单
  • 提供统一构建系统

(我强调)所以,是的,对于Maven来说,有些事情不是最好的解决方案。如果标准发布流程对您有效,请使用release plugin

但如果没有,那就把目光投向别处,而不是落入“everything looks like a nail”的心理陷阱。

个人发展的一个重要步骤是了解你自己的局限性和你所使用的工具的局限性。当一种工具不适合一项工作时,试一试不同的工具,而不是试图扭曲现实。你的生活会更幸福。

sd2nnvve

sd2nnvve6#

也许Phing是另一种解决问题的工具,它很简单,而且你可以定制流程
Phing website

相关问题