在 Cloud Run 中构建和创建 Java 作业

了解如何创建简单的 Cloud Run 作业,从源代码进行部署,以自动将代码打包到容器映像中,将容器映像上传到 Artifact Registry,然后部署到 Cloud Run。除了所示语言之外,您还可以使用其他语言。

须知事项

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 安装 Google Cloud CLI。
  5. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  7. 确保您的 Google Cloud 项目已启用结算功能

  8. 安装 Google Cloud CLI。
  9. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init

编写示例作业

如需使用 Java 编写作业,请执行以下操作:

  1. 创建名为 jobs 的新目录,并转到此目录中:

    mkdir jobs
    cd jobs
    
  2. 在名为 src/main/java/com/example 的子目录中,为实际作业代码创建一个 JobsExample.java 文件。将以下示例行复制到其中:

    
    package com.example;
    
    abstract class JobsExample {
      // These values are provided automatically by the Cloud Run Jobs runtime.
      private static String CLOUD_RUN_TASK_INDEX =
          System.getenv().getOrDefault("CLOUD_RUN_TASK_INDEX", "0");
      private static String CLOUD_RUN_TASK_ATTEMPT =
          System.getenv().getOrDefault("CLOUD_RUN_TASK_ATTEMPT", "0");
    
      // User-provided environment variables
      private static int SLEEP_MS = Integer.parseInt(System.getenv().getOrDefault("SLEEP_MS", "0"));
      private static float FAIL_RATE =
          Float.parseFloat(System.getenv().getOrDefault("FAIL_RATE", "0.0"));
    
      // Start script
      public static void main(String[] args) {
        System.out.println(
            String.format(
                "Starting Task #%s, Attempt #%s...", CLOUD_RUN_TASK_INDEX, CLOUD_RUN_TASK_ATTEMPT));
        try {
          runTask(SLEEP_MS, FAIL_RATE);
        } catch (RuntimeException | InterruptedException e) {
          System.err.println(
              String.format(
                  "Task #%s, Attempt #%s failed.", CLOUD_RUN_TASK_INDEX, CLOUD_RUN_TASK_ATTEMPT));
          // Catch error and denote process-level failure to retry Task
          System.exit(1);
        }
      }
    
      static void runTask(int sleepTime, float failureRate) throws InterruptedException {
        // Simulate work
        if (sleepTime > 0) {
          Thread.sleep(sleepTime);
        }
    
        // Simulate errors
        if (failureRate < 0 || failureRate > 1) {
          System.err.println(
              String.format(
                  "Invalid FAIL_RATE value: %s. Must be a float between 0 and 1 inclusive.",
                  failureRate));
          return;
        }
        if (Math.random() < failureRate) {
          throw new RuntimeException("Task Failed.");
        }
        System.out.println(String.format("Completed Task #%s", CLOUD_RUN_TASK_INDEX));
      }
    }

    Cloud Run 作业允许用户指定作业要执行的任务数量。此示例代码演示了如何使用内置 CLOUD_RUN_TASK_INDEX 环境变量。每个任务代表容器的一个正在运行的副本。 请注意,任务通常并行执行。如果每个任务都可以独立处理一部分数据,则使用多个任务非常有用。

    每个任务都知道其存储在 CLOUD_RUN_TASK_INDEX 环境变量中的索引。内置 CLOUD_RUN_TASK_COUNT 环境变量包含在执行作业时通过 --tasks 参数提供的任务数量。

    此处所示的代码还展示了如何使用内置 CLOUD_RUN_TASK_ATTEMPT 环境变量重试任务,该变量包含此任务重试的次数,从 0 开始(表示第一次尝试),然后每次连续重试时递增 1,上限为 --max-retries

    此外,通过代码,您还可以生成失败来测试重试并生成错误日志,从而查看失败情况。

  3. 创建一个包含以下内容的 pom.xml 文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <!--
    Copyright 2021 Google LLC
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    -->
    <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/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example.run</groupId>
      <artifactId>jobs-example</artifactId>
      <version>0.0.1</version>
      <packaging>jar</packaging>
    
      <!--  The parent pom defines common style checks and testing strategies for our samples.
    	Removing or replacing it should not affect the execution of the samples in anyway. -->
      <parent>
        <groupId>com.google.cloud.samples</groupId>
        <artifactId>shared-configuration</artifactId>
        <version>1.2.0</version>
      </parent>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.target>17</maven.compiler.target>
        <maven.compiler.source>17</maven.compiler.source>
      </properties>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <artifactId>libraries-bom</artifactId>
            <groupId>com.google.cloud</groupId>
            <scope>import</scope>
            <type>pom</type>
            <version>26.32.0</version>
          </dependency>
        </dependencies>
      </dependencyManagement>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.2</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.google.truth</groupId>
          <artifactId>truth</artifactId>
          <version>1.4.0</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.google.cloud</groupId>
          <artifactId>google-cloud-logging</artifactId>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
              <archive>
                <manifest>
                  <addClasspath>true</addClasspath>
                  <mainClass>com.example.JobsExample</mainClass>
                </manifest>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
  4. 创建一个包含以下内容的 project.toml 文件,以使用 Buildpack 支持的 Java 版本进行构建:

    # Default version is Java 11
    #  - See https://cloud.google.com/docs/buildpacks/java#specify_a_java_version
    # Match the version required in pom.xml by setting it here
    #  - See https://cloud.google.com/docs/buildpacks/set-environment-variables#build_the_application_with_environment_variables
    
    [[build.env]]
      name = "GOOGLE_RUNTIME_VERSION"
      value = "17"
    

您的代码已完成,可以封装在容器中。

构建作业容器,将其发送到 Artifact Registry 并部署到 Cloud Run

重要提示:本快速入门假定您在快速入门中使用的项目中拥有所有者或编辑者角色。否则,请参阅 Cloud Run 部署权限Cloud Build 权限Artifact Registry 权限,获取需要的权限。

本快速入门使用“从源代码部署”,以构建容器,将其上传到 Artifact Registry,然后将作业部署到 Cloud Run:

gcloud run jobs deploy job-quickstart \
    --source . \
    --tasks 50 \
    --set-env-vars SLEEP_MS=10000 \
    --set-env-vars FAIL_RATE=0.1 \
    --max-retries 5 \
    --region REGION \
    --project=PROJECT_ID

其中,PROJECT_ID 是您的项目 ID,REGION 是您的区域,例如 us-central1。请注意,您可以将各种参数更改为要用于测试的任何值。SLEEP_MS 模拟工作,FAIL_RATE 导致 X% 的任务失败,因此您可以试验并行情况并重试失败任务。

在 Cloud Run 中执行作业

如需执行刚刚创建的作业,请运行以下命令:

gcloud run jobs execute job-quickstart --region REGION

REGION 替换为您在创建和部署作业时使用的区域,例如 us-central1

后续步骤

如需详细了解如何使用代码源构建容器并推送到代码库,请参阅: