什么是基于Maven的Java应用程序的自动配置,版本控制和部署的实用方法?

And*_*ele 6 java versioning deployment maven

我们将一个中等大小的代码库整合到一个多(多)模块maven项目中.总体而言,整个构建对于不同的系统组件(Web应用程序(.war),实用程序(.jar)等)具有多达十个输出工件.

到目前为止,我们的部署过程基于简单的bash脚本,这些脚本通过maven构建所请求的工件,使用有关工件,目标环境和当前构建时间戳的信息标记scm存储库,然后将工件上载到选定的环境应用程序服务器并发布命令重新启动正在运行的守护进程.通过maven配置文件和资源过滤来配置构建的工件.因此,我们的构建特定于目标环境.

这个过程对我们很有帮助,但出于不同的原因,我想向更复杂的方法迈进.特别是我想摆脱bash脚本.

那么有关基于Maven的Java应用程序的配置,版本控制和部署的最佳实践是什么?

我们的构建是否应该与环境无关,并且配置是通过目标系统上的配置文件完成的?如果是这样,开发人员如何注意新配置选项包含在各种应用程序服务器上的已部署配置文件中?

我们应该使用Maven版本化的Maven发布插件来标记各种构建吗?

配置像Jenkins或Teamcity这样的CI服务器来为我们构建和选择部署我们的工件是一个好主意吗?

Ste*_*lly 7

我想有两个问题空间:

  • 构建工件(理想情况下环境不可知,因为这意味着QA可以获取工件的哈希值,在该工件上运行他们的测试,当需要部署时,验证灰烬并且您知道它已经过QA'd.如果您的构建产生不同的工件根据QA的env或staging env,还是生产env,你必须做更多的工作,以确保生产中的工件已经过质量保证测试并在分期中进行测试)

  • 将工件运送到环境中.如果这一环境要求的工件的配置,运输过程中应包括配置,要么是把适当的配置文件中的目标环境,让文物挑选起来,或通过破解打开文物,配置它们,将它们密封回up(但以可重复和确定的方式)

Maven专为第一个问题空间而设计."Maven方式"是关于生成环境不可知的构建工件并将它们发布到二进制工件存储.如果您查看Maven生命周期,您将看到在将工件deploy编写到Maven存储库(二进制工件存储库)之后阶段停止.简而言之,Maven认为其工作就是在那时完成的.此外,也有单位的生命周期阶段testING和integration-test荷兰国际集团两者均应尽可能与环境无关的假象,但事实并非全套检测,你需要......而是要完成测试,你将需要实际部署将构建的工件转换为真实环境.

许多人试图劫持Maven超越其目标(包括我自己).例如你有cargo-maven-pluginship-maven-plugin上超越行家游戏结束(神器获取到Maven仓库后,即)方面,其触摸.其中,我个人感觉,那ship-maven-plugin(我写的,hency我以前的"包括我自己")是最近的"行家之后"使用,因为默认情况下它的设计工作,而不是在-SNAPSHOT该项目的版本,您已经检查在磁盘上,而不是从远程存储库中提取的同一项目的发行版本,例如

mvn ship:ship -DshipVersion=2.5.1
Run Code Online (Sandbox Code Playgroud)

IMO,货物的目标是在integration-test生命周期的各个阶段使用,但同样,你可以将其用于其他目的.

如果您正在生产收缩包装软件,即用户购买并安装在其系统上的软件,则安装程序本身旨在为最终用户环境配置应用程序.让Maven构建产生安装程序是好的,因为实际的安装程序(至少在某种程度上)与环境无关.好吧,它可能是仅限Microsoft Windows的安装程序,也可能是仅限Linux的安装程序,但它并不关心安装在哪台用户机器上.

但是现在,我们倾向于更多地关注软件即服务,因此我们将软件部署到我们控制的服务器上.它变得更加诱人拖向"Maven的阴暗面",其中创建个人资料被用来调整生成工件的内部配置(毕竟我们只有三种环境,我们部署),我们正在快速移动,所以不要想花时间让应用程序从外部到构建的工件中获取特定于环境的配置(听起来很熟悉?).我之所以称之为黑暗面,是因为你真的在和maven想要工作的方式作斗争......你总是想知道本地存储库中的jar是否是使用不同的配置文件构建的,所以你最终必须做到完全干净建立所有的时间.当谈到时间从QA转向分期或从登台到生产,你需要做的软件完全构建......而所有的单元测试和集成测试最终被再次运行(或者你最终跳过他们,转跳过它们可以在文物他们正在建设),因此可以提供有效你正在生活更难,更复杂的理智......只是为了把几个配置文件到行家的缘故pom.xml......试想,如果你有按照maven的方式,您只需从存储库中获取工件,然后沿着不同的环境移动它,不修改,不受干扰,并使用MD5,SHA1(以及有希望的GPG)签名来证明它是相同的工件.

所以,你问,我们如何编制运输到生产...

那么有很多方法可以解决这个问题.所有这些都有一套类似的核心原则,即

  • 将配方保存到源控制系统中的环境中

  • 理想情况下,配方应该有两个部分,环境不可知部分和环境特定部分.

你可以使用好的旧bash脚本,或者你可以使用更多的"现代"工具,如厨师和木偶,它们是为第二个问题空间而设计的.

建议

您应该使用正确的工具来完成正确的工作.

如果是我,这就是我要做的:

  • 使用Maven Release Plugin剪切版本

  • 构建的工件应始终与环境无关.

  • 构建的工件应包含所有配置选项的"合理默认值".换句话说,如果缺少没有合理默认值的必需配置选项,它们应该快速爆炸,或者如果未指定可选选项,它们应该以合理的方式执行.所需配置选项的示例可能是数据库连接详细信息(除非应用程序很乐意与内存数据库一起运行)

  • 在挑选厨师VS傀儡战争侧(无所谓哪一侧,你可以改变立场,如果你想要的.如果你有和ANT心态,厨师可能更适合你,如果你喜欢依赖管理魔术,木偶可能适合你更好)

  • 开发人员应该在定义部署的chef/puppet脚本方面有发言权,至少是这些脚本中与环境无关的部分.

  • 操作应定义厨师/木偶部署的生产环境特定细节

  • 将所有这些脚本保留在SCM中.

  • 使用Jenkins或任何CI自动执行尽可能多的步骤.Jenkins的推广构建插件是你的朋友.

  • 你的最终游戏是每次提交,只要它通过了所有必需的测试,*可以*自动部署到生产中(或者可能是一个人说"继续"的大门)...注意不要说你实际上这样做每次提交,只有你能做到