前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 ><译文>提升OpenShift上的Java构建效率

<译文>提升OpenShift上的Java构建效率

作者头像
东风微鸣
发布2022-04-21 14:21:43
2.4K0
发布2022-04-21 14:21:43
举报

📘 总结: 整篇文章总结如下: 如果使用OpenShift的S2I, 直接上传源码(而非二进制包)并由OpenShift构建Java应用并构建镜像. 那么以下办法可以提升java构建效率:

  1. 找一个靠谱的制品库(可以是NEXUS或其他)
  2. BuildConfig配置ENV: MAVEN_MIRROR_URL
  3. BuildConfig中使用增量构建 (部分Builder镜像支持该功能)

缩短基于容器平台的Java构建时间

自从我们在2015年7月发布OpenShift 3以来,我从开发人员那里得到的最常见问题之一就是如何为基于Java的构建节省更长的构建时间。在这篇文章中,我将指导您完成加速基于Java Maven的构建的过程,并说明将要采用的其他选项。

您可能知道,OpenShift提供了中间件服务(xPaas),它是针对JBoss,Tomcat,OpenJDK...的一组基于Java的镜像。所有这些镜像都启用了源到镜像(S2I)功能,这将使您的应用程序源代码(使用Maven)构建并分层到应用程序容器中。

使用Maven时,通常在组织中使用Central Artifact Repository Manager来集中和管理所有必需的和生成的依赖项。这还将使您与Internet中工件的实际位置以及某些安全机制以及其他功能隔离。

在担任开发人员和顾问的过程中,我一直为此与Nexus Artifact Manager合作。我不会说这是最好的还是最坏的,而只是说它是我最熟悉的一种。因此,我将在OpenShift安装中使用它。

重要的是要注意,我将描述的所有内容都可以在OpenShift中执行。

我们需要做的第一件事是布置我们的OpenShift体系结构。我已决定将Nexus作为服务在OpenShift中进行部署。为此,我创建了一个Nexus镜像(译者注: 这个镜像不受官方支持),该镜像将在我称为ci的项目中的OpenShift实例中内部构建和部署。该项目名称很重要,因为它将用于引用关系实例。它是服务DNS名称的一部分。

代码语言:javascript
复制
$ oc new-project ci --display-name="OpenShift 持续集成(CI)" --description="该项目拥有所有持续集成所需的基础设施,如Nexus、Jenkins……"
$ oc create -f https://raw.githubusercontent.com/jorgemoralespou/nexus-ose/master/nexus/ose3/nexus-resources.json -n ci
  • 上面的步骤将创建一个名为ci的项目 ,并将向该项目添加一些OpenShift资源,即: 在构建中使用的一个Nexus ServiceAccount。一个BuildConfig建立了Nexus镜像,基于Centos7,将被发布到一个承上启下的ImageStream。部署BuildConfig后,将触发一个内部构建。

📓 备注: 我已经使用了官方的sonatype nexus镜像的Dockerfile作为基础。之后,针对此博客,我添加了自己的要求,例如确保任何用户都可以使用OpenShift受限策略来部署镜像,或者添加配置以使用Red Hat的JBoss maven存储库。

构建需要一些时间,因此请耐心等待!

  • centos7和nexus 的ImageStream定义
  • 两个模板分别称为nexus-ephemeral和nexus-persistent。

作为已加载资源的一部分提供的模板,将允许您使用nexus ServiceAccount部署所构建的Nexus镜像的实例。它还将配置为在端口8081上具有服务,并在您决定的任何主机名上具有路由,以供外部访问。 此外,这些模板将允许您使用PersistentVolume或以短暂模式运行Nexus的持久实例,如果该关系副本死了,您将丢失所有缓存的依赖项。出于测试目的,设置临时实例要容易得多,但是对于更实际的用法,您应该仅考虑持久镜像。

有关如何设置持久性卷的所有说明以及所有要求,请参见Github存储库中的README文件。

在此示例中,我将使用以下命令部署临时版本:

代码语言:javascript
复制
oc new-app --template=nexus-ephemeral --param=APPLICATION_HOSTNAME=nexus.apps.10.2.2.2.xip.io

您还可以使用OpenShift控制台部署nexus实例:

重要的是要了解,在构建过程完成之前将不会部署nexus实例,这可能会花费很多时间,因此请耐心等待!

📓 备注: 提供给APPLICATION_HOSTNAME的值取决于您的安装。我的OpenShift环境默认应用程序域是apps.10.2.2.2.xip.io

我们可以通过提供的APPLICATION_HOSTNAME值访问我们的关系实例,并检查其中的存储库。此关系实例的默认凭据为(admin / admin123)。重要的是要注意,此Nexus服务器已经配置了一些Red Hat JBoss存储库,以允许我们的S2I镜像获取适当的依赖关系。

我们现在需要的是一种指示JBoss S2I构建器镜像将这种nexus实例用作工件存储库管理器的方法。有一些替代方法,我将显示其中两个。

使用提供的S2I构建器

OpenShift 包含JBoss EAP S2I Builder Image。它提供了一个环境变量,可以将其设置为指向Maven镜像URL,毫不奇怪,它称为MAVEN_MIRROR_URL。我将使用该变量通过Nexus实例获取Maven工件。

要检查我们的构建是否将使用我们的内部关系实例,我们可以浏览到公共组页面并验证当前没有存储依赖项。

让我们创建一个新项目,并使用nexus创建一个示例应用程序。

代码语言:javascript
复制
$ oc new-project eap-nexus-builds --display-name="使用Nexus构建jboss" --description="在JBoss EAP中构建应用程序,使用Nexus进行依赖项管理"

对于该应用程序,我们将使用EAP S2I Builder镜像,并且将使用默认的示例项目。然后,我们将设置构建MAVEN_MIRROR_URL。

要通过UI进行先前的配置,您需要使用OpenShift Enteprise 3.1.1或更高版本。您可以使用以下命令创建应用程序

代码语言:javascript
复制
oc create -f https://raw.githubusercontent.com/jorgemoralespou/nexus-ose/master/other/eap-nexus-resources/eap-nexus-resources-all.json

您应该注意到,我使用了我们的nexus实例的内部DNS名称,即nexus.ci.svc.cluster.local,它遵循<service-name>.<project>.svc.cluster.local模式用于DNS服务。这是OpenShift的一项非常强大的功能,可为每项服务提供DNS名称,甚至更多。

在构建应用程序时,我们会注意到,maven依赖项是从我们的nexus实例中提取的,而不是默认的公共Red Hat JBoss的存储库。

构建完成后,我们还将看到nexus存储库工件组如何填充所有已下拉的依赖项。

然后,我们将运行我们的应用程序。

在这里,我们可以在设置MAVEN_MIRROR_URL之前和之后拥有构建的历史视图。OpenShift中的第一个构建始终比任何其他构建花费更长的时间,因为它必须在构建后将所有基础层推送到镜像注册表。连续的构建只会推动应用程序层。从版本2到版本5,我们可以看到不使用Nexus进行正常构建所需的时间,平均需要1分13秒

Build#7引入了设置了MAVEN_MIRROR_URL的更改,但是由于这是设置环境变量之后的第一个构建,因此仍需要1分8秒才能完成。此版本使用所有下拉的依赖项填充Nexus。

在版本8到10中,我们可以看到现在平均构建时间为42秒

可以看出,在引入与工件存储库管理器(例如Nexus)的集成之后,我们平均可以在构建时间上节省31秒

修改S2I构建器

并非总是能够像使用Red Hat提供的中间件服务镜像那样,轻松地使用S2I构建器镜像,该镜像公开了设置Maven镜像的功能。在这些情况下,您需要考虑将这些镜像与工件存储库管理器集成的其他机制。

选项可以变化,从最明显的使用增量构建修改或扩展构建器镜像,到从头开始创建构建器镜像。由于我不喜欢修改现有的镜像,尤其是其他人创建的镜像,因此我将展示如何扩展现有的Wildfly S2I Builder镜像以利用Nexus工件存储库管理器。 相同的方法可以与任何其他构建器镜像一起使用,也可以使用其他一些使用或可以从工件存储库管理器中受益的其他技术,尤其是Nexus或Artifactory支持存储除Java之外的其他语言的依赖项。

我创建了一个文件,该文件将安装与OpenShift安装中提供的Nexus实例一起使用所需的所有必需资源。这些资源是:

  • 3 BuildConfigs,用于Wildfly 8,Wildfly 9和Wildfly 10。
  • 6个ImageStreams,一个用于每个原始ImageStreams每Wildfly版本(的8,9和10),另一种为每个经修饰的S2I为助洗剂镜像Wildfly集成关系(8,9和10)。

我对默认Wildfly S2I构建器镜像所做的更改很简单,就像在自定义S2I构建器镜像中提供一个指向nexus工件存储库管理器的重载settings.xml文件一样。尽管可能更好的选择是提供环境变量以自定义组装过程,但此更改最容易证明此功能。

要安装Wildfly版本:

代码语言:javascript
复制
$ oc new-project wildfly-nexus-builds --display-name="使用Nexus构建Wildfly" --description="在Wildfly中构建应用程序,使用Nexus进行依赖项管理"
$ oc create -f https://raw.githubusercontent.com/jorgemoralespou/nexus-ose/master/builders/wildfly-nexus/wildfly-nexus-resources.json

构建完自定义的Wildfly S2I镜像后,

我们可以使用它们创建一个示例应用程序。

代码语言:javascript
复制
$ oc new-app --docker-image=wildfly-nexus-9 --strategy=source --code=https://github.com/bparees/openshift-jee-sample.git --name='wildfly-nexus-sample'

在这里,我们还看到我们的构建过程正在从提供的Nexus工件存储库管理器中获取所需的maven依赖关系。

第一次构建耗时3分11秒,其中包括使用Github上提供的wildfly-9原始镜像以及拉下该镜像所需的时间。该镜像未执行任何依赖项管理。

在第二个构建中,我更新了BuildConfig以使用wildfly-nexus-9构建器镜像,该构建花费了1分24秒。这样做的原因是Nexus正在缓存所有依赖项,因为我使用了干净的nexus实例。

在第三次和第四次构建中,所有依赖项都已缓存在Nexus中,构建时间分别降至37秒和35秒

与上一个示例一样,使用EAP,通过使用工件存储库管理器(例如Nexus),我们可以在构建时间上获得40秒钟以上的收益。

使用增量构建

我们可以用来改进OpenShift中基于Maven的Java构建的另一个选项是启用增量构建。 不幸的是,并非所有镜像都支持此功能,因为它需要存在save-artifacts脚本,该脚本负责保存构建期间使用的工件。 在我们的情况下,这些将是Maven依赖项。这将具有与将本地Maven存储库放入构建镜像本身相同的行为,但缺点是无法获取以前构建的镜像并从中获取依赖项。

为了测试此模式,我创建了一个示例资源文件,可以轻松对其进行测试。

代码语言:javascript
复制
$ oc new-project eap-incremental-builds --display-name=“EAP增量构建” --description=“使用增量构建模式在EAP中构建应用程序”
$ oc create -f https://raw.githubusercontent.com/jorgemoralespou/nexus-ose/master/other/eap-incremental/eap-incremental-resources.json

创建资源后,让我们进行一些构建并查看时间。

从上图中可以看出,第二个和第三个构建的时间(受益于存储的工件的构建)要短得多:48秒和47秒。 但是,这与使用工件存储库管理器的时间相同。因此,尽管对于那些支持增量模式的镜像而言,它要简单得多,但时间没有任何额外的好处,因为开发人员只需在BuildConfig中指定一个标志。

在此示例中,应用程序和下拉依赖项并没有为初始eap64-openshift S2I镜像增加很大的开销,只有7 MB。

但是我们需要谨慎使用此方法,因为还有其他镜像或应用程序将具有更多的依赖性,并且生成的镜像的大小可能会极大地增长。在下面的示例中使用Fuse Integration Services达到130 MB。

摘要

对于我们构建的每个应用程序,通过将其依赖项缓存到工件存储库管理器中,我们将获得性能优势。最初,我们将从每个应用程序的第二个及后续版本的性能收益中获益,但是随着工件存储库管理器存储越来越多的依赖关系,这种好处也将在新应用程序的初始版本中体现出来,并且大多数依赖关系已经已缓存。

另外,我们可以使用增量构建在基于Java的构建上获得更好的性能,但重要的是要理解,即使这种方法更易于设置,也存在一些缺点,例如需要镜像支持增量模式。 请注意,在这种情况下,生成过程会将依赖项保存在要生成的镜像中。这意味着,如果连续的构建在不同的节点上运行,则每个节点都必须首先从OpenShift的Docker注册表中拉取镜像,这可能比再次拉取依赖项花费的时间更长。

使用Nexus或任何其他工件存储库依赖项管理器的最重要好处是安全性和一个开发人员/内部版本下载的依赖项将在使用相同依赖项的所有内部版本中重复使用的事实。在增量构建的情况下,只有在先前构建期间下载的依赖项可以重复使用,并且只能由同一构建重复使用。这可能会对任何基于Java的组织产生巨大影响。

在此博客中,我重点介绍了如何改善OpenShift中基于Maven的Java构建的构建时间,但另一个非常重要的主题是使用内部DNS服务名称来从一个项目引用到另一个项目。唯一需要注意的是,如果我们使用多租户OVS网络插件,则集群管理员将必须使ci项目对所有其他项目可见:

代码语言:javascript
复制
$ oc adm pod-network make-projects-global ci
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 东风微鸣技术博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 缩短基于容器平台的Java构建时间
  • 使用提供的S2I构建器
  • 修改S2I构建器
  • 使用增量构建
  • 摘要
相关产品与服务
持续集成
CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档