2013-07-29 24 views
1

环境:建筑文物多个环境,并将其上传到S3

  • 周边有十几服务:两场战争和JAR(与狸包装上运行)
  • 每个服务被部署到发展,分段和生产:环境使用不同的web.xml文件,Spring配置文件(在Tanuki包装器上设置)...
  • 我们希望将工件存储在AWS S3上,以便我们的EC2实例可以轻松获取这些工件:某些服务在多台机器上运行,AutoScaling实例在引导,开发后自动获取最新版本一旦被更新牛逼的文物应自动进行部署,...

我们当前的部署过程是这样的:

  1. 詹金斯构建并测试我们的代码
  2. 一旦我们很满意,我们做Artifactory plugin(仅用于生产部署;开发和分期文物都是基于普通詹金斯版本)
  3. 我们使用Promoted Builds plugin有3种不同的推广工作为每个项目(开发,分期,生产)建神器所希望的环境,然后把它上传到S3

这个工程主要是OK,但是我们遇到了多烦恼:

  1. 的Artifactory的插件无法标签和源代码更新,由于未能提交到库来(这可能是具体到CloudBees ,我们的Jenkins提供商)。没关系 - 我们可以手动做到这一点。
  2. Jenkins S3 plugin无法正确使用多个上传目标(我们正在为每个环境使用一个目标) - 当您保存配置时,它会尝试上传到所有目标并复制设置:JENKINS-18563。没关系 - 我们正在使用一个shell脚本进行上传,工作正常。
  3. 升级作业有时会失败,因为它们可以在与原始构建不同的实例上运行 - 导致失败(构建是因为文件丢失)或过时构建(因为正在使用旧版本)。再次,这可能是由于CloudBees提供的特定设置而发生的。这可以通过再次运行构建来解决,希望这次推广作业可以在其构建的同一实例上运行(这是我理解中的纯粹运气)。

我们已经被告知由CloudBees的运行推广工作前做一个码结账,因为工作空间是短暂的,它不能保证它的存在,或者它是最新的。但是,升级作业中的shell脚本似乎不符合其他StackOverflow thread中所述的环境变量,即使它们链接在textarea字段下方。所以svn checkout ${SVN_URL} -r ${SVN_REVISION}不起作用。

我敢肯定,这可以通过一些解决方法来解决,但肯定我必须做一些非常错误的事情。我假设许多其他人都以类似的方式部署他们的应用程序,并且必须有更好的方式 - 没有各种解决方法和烦恼。

感谢任何指针和阅读一切到最后!

+0

你能否详细说明为什么你的Artifactory不能提交源代码管理? – JBaruch

+0

看起来像提交和标记是好的,毕竟它只是缺少最新快照的更新。我已经创建了一个单独的问题,因为这只是一个小问题,而不是原始问题的核心:http://stackoverflow.com/questions/17921881/jenkins-artifactory-plugin-updating-to-the-latest -snapshot-on-git – xeraa

回答

2
  • 您面临的最大问题是您实际上想要在升级过程中进行构建。推广的构建插件旨在执行一些小操作,主要针对构建的归档工件,或执行标记或其他此类操作。

    • 该设计确保它在从属设备上获得工作区。但是(并且这是Jenkins的一件事情,不是CloudBees特有的)首先,您得到的工作空间不需要是用于您尝试提升的构建的工作空间。这可能是:

      1. 一个空的工作区
      2. 最近该项目的建设(这可能比你正试图推动新的版本)
      3. 的较早构建的工作空间的工作空间该项目(当你无法进入具有最新版本项目的奴隶)

      现在你完全取决于你的Jenkins集群的负载。在CloudBees上运行时,通常最有可能遇到以上两种情况之一。

    • 因此,您在促销活动中的行为应该是“自给自足的”。因此,例如,他们会将存档的工件复制到特定的目录中,然后使用这些复制的工件来完成它们的“事情”。或者他们会触发一个下游构建,传递来自构建的参数。否则将不使用任何本地状态执行远程服务器上的一些行动(即翻转在蓝绿色的部署交换机)

  • 在你的情况,你的战斗在多个方面。你正在与之战斗的第二方面是你正在与Maven战斗。

    • 当构建配置文件处于活动状态时会产生不同的非等价工件,Maven不喜欢它。
    • Maven大概可以用release配置文件生成一个版本的工件,并将JavaScript缩小并且可能会除去调试信息(尽管如果可以避免,它会更好)......但这是因为两个工件是等效的。 JavaScript缩小的web应用程序应该和未缩小的web应用程序一样工作(除非缩小引入了错误)
    • 您使用配置文件来构建完全不同的工件。这很糟糕,因为Maven不会将活动配置文件存储为部署到Maven存储库的信息的一部分。因此,当您声明对某个工件的依赖关系时,您不知道在构建该工件时哪个配置文件处于活动状态。这样做的一个常见副作用是最终会出现裂脑工件,其中一个复合工件的一部分正在与开发数据库交谈,另一部分正在与生产数据库交谈。当开发人员想要切换到构建生产版本时,他们会定期运行mvn clean install -Pprod && mvn clean install -Pprod,因为过去它们已经被裂脑文物烧毁,您可以知道这种糟糕的代码味道。这是设计不良的一个症状,而不是Maven的问题(除非能够创建特定于架构的Maven构件的构建,但它们可以构成他们自己的问题)
    • “Maven方式”处理为不同部署环境创建不同工件的方法是使用单独的模块来重新包装“通用”工件。正如Maven处理不良架构的微妙方法所典型的那样,您将需要为每个想要定位的环境添加重新包装模块......这不鼓励拥有许多不同的目标环境......(例如,如果您有10个webapps/services部署和三个目标部署环境中,您将拥有10个通用模块和3x10个目标特定模块...提供40个模块构建),并希望能够鼓励您找到一种方法,让部署时工件自动发现其正确的配置。
  • 我怀疑破解解决方案最安全的方法是依靠复制归档的工件。

    1. 在主构建过程中,创建一个文件,用于检出与构建版本相同的修订版本,例如,

      echo '#!/usr/bin/env sh' > checkout.sh 
      echo "svn revert . -R" >> checkout.sh 
      echo "svn update --force -r ${SVN_REVISION}" >> checkout.sh 
      

      虽然你可能想写一些更健壮的东西,确保您处于SVN工作副本,确保工作副本使用正确的远程URI,删除任何不需要的文件等。

    2. 确保您创建的脚本已存档。

    3. 在您的升级过程开始时,将已归档的checkout.sh复制到工作区,然后运行该脚本。你应该能够像以前一样完成你以后的所有推广步骤。

  • 一个更好的解决办法是为每个推广过程中创造积累的工作,并通过通过SVN修订作为构建参数(但将需要更多的工作来设置你(因为你已经有了推广流程设置)

  • 最好的解决方案是修复您的架构,以便生成可以从目标环境发现其正确配置的工件,因此您可以将相同的工件部署到每个所需的环境而无需重新构建人造物品

+0

感谢您的详细解答!假设我们可以创建一个通用工件(我将不得不与其他开发人员讨论这个问题),那么我怎样才能将它复制到S3(因为'$ WORKSPACE/target'将不可用)?至少我必须重命名WAR/JAR文件(''foo-latest.war'')并将其上传到S3 - 所以EC2实例有一个静态URL来获取应用程序。 – xeraa

+0

回答我自己的问题:您需要一个构建后步骤来存档工件。 – xeraa