【问题标题】:How to speedup java maven build on Google Cloud Build (100s of dependencies)如何在 Google Cloud Build 上加速 java maven 构建(100 个依赖项)
【发布时间】:2019-10-01 04:35:04
【问题描述】:

我正在使用 Google Cloud Build 构建一个具有 100 多个依赖项的 java 项目。默认情况下,本地 maven 存储库缓存将为空,并且它每次构建时都会下载所有依赖项

google 文档仅建议“使用 Google Cloud Storage 缓存目录”https://cloud.google.com/cloud-build/docs/speeding-up-builds,但同步 7000 个文件需要很长时间(这意味着构建速度较慢)

只有一个依赖是 5 个文件

repository/org/mockito
repository/org/mockito/mockito-core
repository/org/mockito/mockito-core/2.15.0
repository/org/mockito/mockito-core/2.15.0/mockito-core-2.15.0.jar
repository/org/mockito/mockito-core/2.15.0/mockito-core-2.15.0.jar.sha1
repository/org/mockito/mockito-core/2.15.0/mockito-core-2.15.0.pom
repository/org/mockito/mockito-core/2.15.0/mockito-core-2.15.0.pom.sha1
repository/org/mockito/mockito-core/2.15.0/_remote.repositories

一个示例 cloudbuild.yaml 文件

steps:
- name: gcr.io/cloud-builders/gsutil
  args: ['rsync', '-r', 'gs://my-mavencache-bucket/repository', '.']

- name: 'gcr.io/$PROJECT_ID/mvn'
  args: ['package']
...

我想将 gs://my-mavencache-bucket 挂载为一个卷 - 但我没有看到这样做的选项

【问题讨论】:

  • 你有这个项目的例子吗?此外,您是否使用最新版本的 Maven 和所有插件?等
  • 你能用关于慢的指标更新你的问题吗?你能提供一个构建需要多长时间的测量吗?如果你在 PC 上本地编译,没有任何东西下载到缓存中,需要多长时间?
  • 我使用 maven 很多年了,问题不在于 maven 的版本或某些配置,它与 google cloud build 的工作方式有关 - 构建是一组步骤,其中每个步骤相当于 docker run 命令,/workspace 是这些步骤共享的公共目录。鉴于 Google Cloud Build 是推荐的构建标准,并且我正在使用 java 单体应用程序(相当主流的用例),我希望现在能找到一个示例,但还没有运气
  • 似乎疯狂的谷歌 cloudbuild 缺少这个最基本的需求。在我们的例子中,构建需要 15 分钟而不是 2 分钟。 Jenkins、Bitbucket 等负责缓存 maven 存储库。

标签: java maven google-cloud-build


【解决方案1】:

经过多次试验,这个解决方案似乎效果很好。 google-storage-wagon。这个 maven 插件提供了一种从 google 读取和发布 maven 工件的机制 数据桶

Maven pom.xml 包含

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
...
    <repositories>
        <repository>
            <id>my-repo-bucket-release</id>
            <url>gs://bucket-ave-build-artifact/external</url>
            <releases>
                <enabled>true</enabled>
                <!-- TODO figure out why checksums do not match when artifact pulled from GCP -->
                <checksumPolicy>ignore</checksumPolicy>
            </releases>
        </repository>
    </repositories>

    <distributionManagement>
        <snapshotRepository>
            <id>my-repo-bucket-snapshot</id>
            <url>gs://my-build-artifact-bucket/snapshot</url>
        </snapshotRepository>
        <repository>
            <id>my-repo-bucket-release</id>
            <url>gs://my-build-artifact-bucket/release</url>
        </repository>
    </distributionManagement>
...
        <extensions>
            <extension>
                <groupId>com.gkatzioura.maven.cloud</groupId>
                <artifactId>google-storage-wagon</artifactId>
                <!-- version 1.8 seems to produce exception, ticket logged -->
                <version>1.7</version>
            </extension>
        </extensions>

    </build>

而 cloudbuild.yaml 很简单

steps:
 - name: 'gcr.io/cloud-builders/mvn'
  # -X here simply for verbose maven debugging
  args: ['deploy', '-X']

这将:

  1. maven 将工件发布到数据桶 gs://my-build-artifact-bucket/release
  2. 下载外部依赖 来自 gs://my-build-artifact-bucket/external(如果它们存在于此目录中)

【讨论】:

  • 另一种机制是构建一个自定义 docker 镜像,其中包含 .m2 缓存中的大部分 maven 工件。这会导致自定义构建步骤的启动时间稍慢,因为需要从cloud.google.com/container-registry 中提取较大的图像。
【解决方案2】:

我发现 google-storage-wagon 包非常好,但在身份验证和同步时间方面缺乏。

我自己实现了它,如下所示。有关服务帐户的更多信息,请参阅此答案:https://stackoverflow.com/a/56610260/1236401

因此,假设您手边有服务帐户 key.json 文件,并且您有 SERVICE_ACCOUNT 的名称以及存储桶 BUCKET_PATH,这就是基本的 Dockerfile:

FROM maven:3.6.1-jdk-12

ENV MAVEN_PATH="/root/.m2" \
    BUCKET_PATH="gs://mugen-cache/maven"
COPY key.json /key.json

# install gcloud sdk
RUN mkdir -p $MAVEN_PATH && \
    yum install -y curl which && \
    curl https://sdk.cloud.google.com | bash > /dev/null
ENV PATH="${PATH}:/root/google-cloud-sdk/bin" \
    SERVICE_ACCOUNT="mugen-build@mugen.iam.gserviceaccount.com"
# authenticate service account and install crcmod - https://cloud.google.com/storage/docs/gsutil/addlhelp/CRC32CandInstallingcrcmod
RUN gcloud auth activate-service-account $SERVICE_ACCOUNT --key-file=/key.json && \
    yum install -y gcc python-devel python-setuptools redhat-rpm-config
RUN curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py" && \
    python get-pip.py && \
    pip uninstall crcmod && \
    pip install --no-cache-dir -U crcmod

RUN echo "Syncing m2 in..." && \
    gsutil -q -m rsync -r $BUCKET_PATH $MAVEN_PATH && \
    echo "Downloaded $(find $MAVEN_BUCKET -type f -name "*.pom" | wc -l) packages"

# ... build and stuff

RUN echo "Syncing m2 out..." && \
   gsutil -q -m rsync -r $MAVEN_PATH $BUCKET_PATH

此处的一些说明特定于基本映像(即基于 REHL 的 Oracle Linux 服务器),但您应该能够提取重要的细节以使其适用于您的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-19
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2023-03-13
    • 2011-10-29
    • 1970-01-01
    • 2021-07-10
    相关资源
    最近更新 更多