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 分析图片,以检测其是否为食品。对于未通过此验证的图片,菜单项状态将更新为“失败”,随后会被清理作业删除。

学习内容
在本实验中,您将学习如何完成以下操作:
- 创建 Cloud Run 作业
- 执行 Cloud Run 作业
- 创建 Cloud Scheduler 作业
- 验证作业执行情况
前提条件
- 本实验假设您熟悉 Cloud 控制台和 shell 环境。
- 具备 Cloud Run 和 Cloud Scheduler 方面的经验会有所帮助,但这不是硬性要求。
2. 设置和要求
Cloud 项目设置
- 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个。



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

在 Cloud Shell 中,运行以下命令以从此代码库克隆应用代码,然后前往包含菜单服务的目录:
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/menu-service
使用设置脚本将 Menu 服务部署到 Cloud Run。菜单服务是一个基于 Java 的微服务,使用 Quarkus 框架构建,并使用 Cloud SQL Postgres 数据库作为其后端。Menu 服务是您将在后续步骤中创建的 Cloud Run 作业的运行时依赖项。
./setup.sh
部署大约需要 10 分钟才能创建所有必需的组件。
执行上述命令后,继续执行后续步骤。
3. 探索 Cloud Run 作业代码
点击加号图标,在 Cloud Shell 中打开一个新标签页。

前往包含清理服务和构成作业的查看文件的目录:
cd ~/cymbal-eats/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"]
以下列出的实际清理脚本包含一些命令,用于获取处于失败状态的菜单项列表,并通过向 Menu 服务发出 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_AGE和MENU_SERVICE_URL环境变量将在部署期间设置,并由 Cloud Run 作业传递。FAILED_ITEM_AGE- 失败项将被删除前的分钟数。MENU_SERVICE_URL- Cymbal Eats 菜单服务网址。
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 并查看已发布的映像:

切换回第二个 Cloud Shell 标签页。运行以下命令,描述 Menu 服务并将网址保存到环境变量中。此环境变量将用于配置 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。

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

(可选)如果您想更改“失败项存在时间”或“菜单服务网址”变量,可以在创建 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
切换到“日志”标签页,查看作业的输出。您应该会在日志中看到“Failed Item Age”和“Menu Service 网址”。

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 Scheduler 作业中使用的服务账号授予 Cloud Run Invoker 角色:
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 参数:
REGION和PROJECT_ID- 部署清理服务作业的 Cloud Run 区域和项目 IDcleanup-service- Cloud Run 作业的名称
在控制台中前往 Cloud Scheduler,查看已创建的调度器作业:

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

6. 测试 Cloud Run 作业
使用 Menu Service 端点,查看现有菜单项及其状态:
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 分钟。要删除菜单项,该菜单项需要存在 1 分钟,如 FAILED_ITEM_AGE 参数所设置的那样。
您可以等待下一次预定运行,也可以从控制台强制执行作业。
您可以通过界面或从命令行以多种方式触发作业。
在此示例中,请在 Cloud Shell(选项 3)中运行命令以触发作业。
- 通过从“操作”菜单中选择“强制运行作业”来从 Cloud Scheduler 运行作业。

- 通过点击“执行”按钮,从 Cloud Run 作业中执行。

- 通过在 Cloud Shell 中运行以下命令:
gcloud beta run jobs execute cleanup-service --region=$REGION
前往 Cloud Run JOBS 部分,打开日志标签页,然后验证菜单项是否已删除。

过滤包含“删除”关键字的日志,以查找相关日志。

使用菜单服务端点通过 REST 端点检查现有菜单项。
curl ${MENU_SERVICE_URL}/menu | jq
输出:
您会看到 2 个处于 Ready 状态的菜单项。
7. 恭喜!
恭喜,您已完成此 Codelab!
所学内容:
- 如何创建 Cloud Run 作业
- 如何执行 Cloud Run 作业
- 如何创建 Cloud Scheduler 作业
- 如何验证作业执行情况
后续步骤:
探索其他 Cymbal Eats Codelab:
- 使用 Eventarc 触发 Cloud Workflows
- 触发 Cloud Storage 中的事件处理
- 从 Cloud Run 连接到专用 CloudSQL
- 从 Cloud Run 连接到全代管式数据库
- 使用 Identity Aware Proxy (IAP) 保护无服务器应用
- 安全地部署到 Cloud Run
- 保护 Cloud Run 入站流量的安全
- 从 GKE Autopilot 连接到专用 AlloyDB
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
若要避免产生费用,最简单的方法是删除您为本教程创建的项目。