使用 Cloud Scheduler 触发 Cloud Run 作业

1. 概览

在本实验中,您将创建一个 Cloud Run 作业并设置 Cloud Scheduler 作业。您将使用设置脚本部署 Cymbal Eats Menu Service。您将创建一个 Cloud Run 作业,用于对 Cymbal Eats Menu Service 进行 API 调用。您将使用 Google Cloud CLI 执行作业,并为作业设置时间表。您将通过查看日志并对菜单服务进行 API 调用来确认菜单项已删除,从而验证执行情况。

什么是 Cloud Run 作业?

Cloud Run 作业运行的容器不处理 Web 请求,但负责执行运营任务或数据处理。容器将运行任务,并在完成后退出。

清理服务作业

清理服务作业将检索状态为“失败”的菜单项并将其删除。创建新菜单项后,系统会使用 Vision API 分析图像,以检测该菜单项是否为食品。对于未通过此验证的图片,菜单项状态将更新为“失败”,然后由清理作业删除。

d74200f0bd14d350.png

学习内容

在本实验中,您将学习如何完成以下操作:

  • 创建 Cloud Run 作业
  • 执行 Cloud Run 作业
  • 创建 Cloud Scheduler 作业
  • 验证作业执行情况

前提条件

  • 本实验假定您熟悉 Cloud 控制台和 Shell 环境。
  • 以前的 Cloud Run 和 Cloud Scheduler 经验非常有帮助,但并非强制要求。

2. 设置和要求

Cloud 项目设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常您不在乎这是什么在大多数 Codelab 中,您都需要引用项目 ID(它通常标识为 PROJECT_ID)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且该 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即某些 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。如需关停资源,以免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除整个项目。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

环境设置

点击搜索栏右侧的图标,激活 Cloud Shell。

eb0157a992f16fa3.png

在 Cloud Shell 中运行以下命令,从代码库中克隆应用代码,并转到包含菜单服务的目录:

git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/menu-service

使用设置脚本将“菜单”服务部署到 Cloud Run。“菜单”服务是一种基于 Java 的微服务,使用 Quarkus 框架构建,使用 Cloud SQL Postgres 数据库作为后端。“菜单”服务是您将在以下步骤中创建的 Cloud Run 作业的运行时依赖项。

./setup.sh

部署需要大约 10 分钟时间才能创建完所有必需的组件。

执行上述命令后,继续执行后续步骤。

3. 探索 Cloud Run 作业代码

点击加号图标,在 Cloud Shell 中打开一个新标签页。

45f480cd1b9a995

转到包含清理服务的目录,并查看构成该作业的文件:

cd ~/cymbal-eats/cleanup-service

此目录中的 cleanup-service 包含一个 Dockerfile,用于定义具有所需依赖项(httpie、jq)的清理服务作业的容器映像。

Dockerfile

FROM ubuntu:latest 
RUN apt-get update && apt-get install -y httpie jq && apt-get clean
COPY script.sh /
RUN chmod +x /script.sh
CMD ["/script.sh"]
ENTRYPOINT ["/bin/bash"]

实际的清理脚本(如下所示)包含一些命令,用于获取处于失败状态的菜单项列表,并通过对“菜单”服务进行 API 调用来删除这些菜单项。

script.sh

echo "FAILED_ITEM_AGE=$FAILED_ITEM_AGE"
echo "MENU_SERVICE_URL=$MENU_SERVICE_URL"
# Failed items older than FAILED_ITEM_AGE in minutes
for id in $(http GET $MENU_SERVICE_URL/menu/failed | jq '[.[] | select(.updateDateTime < ((now - 60 * (env.FAILED_ITEM_AGE | tonumber) )| strftime("%Y-%m-%dT%H:%M:%S.%f")))]'| jq '.[].id'); do
  echo "Deleting Menu Item : $MENU_SERVICE_URL/menu/$id"
  http GET $MENU_SERVICE_URL/menu/$id
  http DELETE $MENU_SERVICE_URL/menu/$id
done

# Processing items older than FAILED_ITEM_AGE in minutes
for id in $(http GET $MENU_SERVICE_URL/menu/processing | jq '[.[] | select(.updateDateTime < ((now - 60 * (env.FAILED_ITEM_AGE | tonumber))| strftime("%Y-%m-%dT%H:%M:%S.%f")))]'| jq '.[].id'); do
  echo "Deleting Menu Item : $MENU_SERVICE_URL/menu/$id"
  http GET $MENU_SERVICE_URL/menu/$id
  http DELETE $MENU_SERVICE_URL/menu/$id
done

请注意关于脚本的以下事项:

  • FAILED_ITEM_AGEMENU_SERVICE_URL 环境变量将在部署期间设置,并由 Cloud Run 作业传递。
  • FAILED_ITEM_AGE - 删除失败项之前经过的分钟数。
  • MENU_SERVICE_URL - Cymbal Eats Menu 服务网址。

4. 创建 Cloud Run 作业

接下来,您将构建容器映像并将其发布到 Artifact Registry。

此容器映像将用于创建 Cloud Run 作业。

启用服务 API:

gcloud services enable \
    run.googleapis.com \
    artifactregistry.googleapis.com \
    cloudscheduler.googleapis.com \
    --quiet

设置环境变量:

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export PROJECT_NAME=$(gcloud projects describe $PROJECT_ID --format='value(name)')
export REGION=us-east1
export MENU_SERVICE_NAME=menu-service

创建一个新的 Artifact Registry 代码库来存储用于清理作业的 Docker 映像:

gcloud artifacts repositories create cymbal-eats --repository-format=docker --location=$REGION

使用 Cloud Build 构建容器映像,并通过一条命令将其推送到 Artifact Registry:

gcloud builds submit -t $REGION-docker.pkg.dev/$PROJECT_NAME/cymbal-eats/cleanup-service:latest

输出示例:

DURATION: 35S
SOURCE: gs://cymbal-eats-14906-569_cloudbuild/source/1657126400.933586-dc3e91ec85934a55bb6d2f7012611365.tgz
IMAGES: us-east1-docker.pkg.dev/cymbal-eats-14906-569/cymbal-eats/cleanup-service (+1 more)
STATUS: SUCCESS

发布完成后,前往 Artifact Registry 并查看已发布的映像:

fb95ae38baa7c543.png

切换回第二个 Cloud Shell 标签页。运行以下命令来描述菜单服务,并将网址保存到环境变量。此环境变量将用于配置 Cloud Run 作业。

MENU_SERVICE_URL=$(gcloud run services describe $MENU_SERVICE_NAME \
 --region=$REGION \
 --format=json | jq \
 --raw-output ".status.url")

创建 Cloud Run 作业以清理存在时间超过 1 分钟的失败菜单项 [由 FAILED_ITEM_AGE 设置]。

gcloud beta run jobs create cleanup-service \
  --image=$REGION-docker.pkg.dev/$PROJECT_NAME/cymbal-eats/cleanup-service:latest \
  --set-env-vars MENU_SERVICE_URL=$MENU_SERVICE_URL \
  --set-env-vars FAILED_ITEM_AGE=1 \
  --region $REGION

输出示例:

Creating Cloud Run job [cleanup-service] in project [cymbal-eats] region [us-east1]
OK Creating job... Done.
Done.
Job [cleanup-service] has successfully been created.

前往控制台中的 Cloud Run 作业部分,并查看已创建的作业。

点击该作业并浏览可用标签页:“历史记录”、“日志”、“配置”和“YAML”。

b12c8e312de3b66.png

通过查看控制台中作业的配置部分,验证是否已设置环境变量:

724c2919d05349c8

(可选)如果要更改“失败项的存在时间”或“菜单服务”网址变量,可以在创建 Cloud Run 作业后使用更新命令:

gcloud beta run jobs update cleanup-service \
  --image=$REGION-docker.pkg.dev/$PROJECT_NAME/cymbal-eats/cleanup-service:latest \
  --set-env-vars MENU_SERVICE_URL=$MENU_SERVICE_URL \
  --set-env-vars FAILED_ITEM_AGE=1 \
  --region $REGION

如需验证作业,请运行以下命令来执行 Cloud Run 作业:

gcloud beta run jobs execute cleanup-service --region=$REGION

输出示例:

OK Creating execution... Done.                                   
  OK Provisioning resources...
Done.
Execution [cleanup-service-rlxs4] has successfully started running.

View details about this execution by running:
gcloud beta run jobs executions describe cleanup-service-rlxs4
 

切换到日志标签页以查看作业的输出。您应该会在日志中看到“失败的商品存在时间”和“菜单服务”网址。

518cb00036a2561f

5. 为 Cloud Run 作业设置时间表

Cloud Scheduler 是一项全托管式企业级 cron 作业调度服务。它让您几乎可以安排任何作业,包括批量作业、大数据作业、云基础架构操作等。

使用 Cloud Scheduler 作业时,一种安全最佳实践是使用单独的凭据执行每个作业。在此步骤中,创建一个供清理调度器作业使用的服务账号。

export SCHEDULER_SERVICE_ACCOUNT=cleanup-scheduler-job-sa

gcloud iam service-accounts create ${SCHEDULER_SERVICE_ACCOUNT}

Cloud Scheduler 作业需要具有调用 Cloud Run 作业的权限。

Cloud Run Invoker 角色授予 Cloud Scheduler 作业中使用的服务账号:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member="serviceAccount:${SCHEDULER_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/run.invoker"

接下来,您将设置一个时间表来运行清理服务作业。

Cloud Scheduler 支持多种目标类型

  • HTTP
  • Pub/Sub
  • App Engine HTTP

您将使用 HTTP 目标类型创建调度器作业。

出于演示目的,您将安排其每 5 分钟运行一次。

gcloud scheduler jobs create http cleanup-schedule \
    --location $REGION \
    --schedule="*/5 * * * *" \
    --uri="https://$REGION-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/$PROJECT_ID/jobs/cleanup-service:run" \
    --http-method POST \
    --oauth-service-account-email ${SCHEDULER_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com

查看用于调用 Cloud Run 作业的 uri 参数:

  • REGIONPROJECT_ID - 部署清理服务作业的 Cloud Run 区域和项目 ID
  • cleanup-service - Cloud Run 作业的名称

在控制台中前往 Cloud Scheduler,以查看已创建的调度器作业:

3bc9120df7fc6ed

查看“操作”菜单下的可用选项。

7945908025dd2f2b

6. 测试 Cloud Run 作业

使用“菜单服务”端点,查看现有菜单项及其状态:

curl ${MENU_SERVICE_URL}/menu | jq

输出:

您将看到 3 个状态为“Ready”的菜单项。

将菜单项 1 的状态更改为 Failed

curl -X PUT "${MENU_SERVICE_URL}/menu/1" \
  -H 'Content-Type: application/json' \
  -d '{"status": "Failed"}' | jq

等待 1 分钟。根据 FAILED_ITEM_AGE 参数的设置,菜单项需要存在 1 分钟才会被删除。

您可以等待下一次预定的运行,也可以从控制台强制执行作业。

您可以通过界面或命令行多种方式触发作业。

在本示例中,在 Cloud Shell 中运行命令(选项 3)以触发作业。

  1. 通过 Cloud Scheduler 选择“强制运行作业”选择“操作”菜单

6c8cbeae6165ba4a

  1. Cloud Run 作业中,点击“执行”按钮。

229c22288882b5c3

  1. 在 Cloud Shell 中运行以下命令:
gcloud beta run jobs execute cleanup-service --region=$REGION

前往“Cloud Run 作业”部分,打开日志标签页,验证菜单项是否已删除。

50829ae27b135b2d

过滤日志以执行“删除”操作关键字来查找日志。

d94fb9e444b1c1b8.png

使用“菜单服务”端点通过 REST 端点检查现有菜单项。

curl ${MENU_SERVICE_URL}/menu | jq

输出:

您将看到 2 个处于“Ready”状态的菜单项。

7. 恭喜!

恭喜,您已完成此 Codelab!

所学内容:

  • 如何创建 Cloud Run 作业
  • 如何执行 Cloud Run 作业
  • 如何创建 Cloud Scheduler 作业
  • 如何验证作业执行情况

后续步骤:

探索其他 Cymbal Eats Codelab:

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。