本教程介绍如何使用 Workflows 将一系列服务关联在一起。通过连接使用 Cloud Run 函数的两项公共 HTTP 服务、外部 REST API 和专用 Cloud Run 服务,您可以创建灵活的无服务器应用。
目标
在本教程中,您将使用 Google Cloud CLI 创建一个单一工作流,一次连接一项服务:
- 部署两项 Cloud Run 函数服务:第一个函数生成一个随机数字,然后将该数字传递给第二个函数(此函数会乘以该数字)。
- 使用 Workflows 将两个 HTTP 函数连接在一起。执行工作流并返回结果,然后将其传递给外部 API。
- 使用 Workflows 连接外部 HTTP API,该 API 会返回给定编号的
log
。执行工作流并返回结果,然后将其传递给 Cloud Run 服务。 - 部署 Cloud Run 服务以仅允许经过身份验证的访问。该服务会返回给定数字的
math.floor
。 - 使用 Workflows 连接 Cloud Run 服务,执行整个工作流并返回最终结果。
下图简要展示了该过程并直观呈现了最终工作流:
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
准备工作
您的组织定义的安全限制条件可能会导致您无法完成以下步骤。如需了解相关问题排查信息,请参阅在受限的 Google Cloud 环境中开发应用。
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry, Cloud Build, Cloud Run functions, Cloud Run, Cloud Storage, and Workflows APIs:
gcloud services enable artifactregistry.googleapis.com
cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com storage.googleapis.com workflows.googleapis.com - Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry, Cloud Build, Cloud Run functions, Cloud Run, Cloud Storage, and Workflows APIs:
gcloud services enable artifactregistry.googleapis.com
cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com storage.googleapis.com workflows.googleapis.com - 更新 Google Cloud CLI 组件:
gcloud components update
- 如果您在 Cloud Shell 中运行命令,则您已经使用 gcloud CLI 进行了身份验证;否则,请使用您的账号登录:
gcloud auth login
- 设置本教程中使用的默认位置:
gcloud config set project PROJECT_ID export REGION=REGION gcloud config set functions/region ${REGION} gcloud config set run/region ${REGION} gcloud config set workflows/location ${REGION}
将
REGION
替换为您选择的受支持的 Workflows 位置 -
如果您是项目创建者,则会被授予基本 Owner 角色 (
roles/owner
)。默认情况下,此 Identity and Access Management (IAM) 角色可提供完全访问大多数 Google Cloud 资源所需的权限,您可以跳过此步骤。如果您不是项目创建者,则必须向主账号授予项目的必需权限。例如,主账号可以是 Google 账号(针对最终用户)或服务账号(针对应用和计算工作负载)。如需了解详情,请参阅事件目标位置的角色和权限页面。
所需权限
如需获得完成本教程所需的权限,请让您的管理员为您授予项目的以下 IAM 角色:
-
Cloud Build Editor (
roles/cloudbuild.builds.editor
) -
Cloud Functions Developer (
roles/cloudfunctions.developer
) -
Cloud Run Admin (
roles/run.admin
) -
Create Service Accounts (
roles/iam.serviceAccountCreator
) -
Project IAM Admin (
roles/resourcemanager.projectIamAdmin
) -
Service Account User (
roles/iam.serviceAccountUser
) -
Service Usage Consumer (
roles/serviceusage.serviceUsageConsumer
) -
Storage Admin (
roles/storage.admin
) -
Workflows Editor (
roles/workflows.editor
)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
-
Cloud Build Editor (
部署第一项 Cloud Run 函数服务
收到 HTTP 请求后,此 HTTP 函数会生成一个介于 1 到 100 之间的随机数字,然后以 JSON 格式返回该数字。
创建名为
randomgen
的目录并切换到该目录:mkdir ~/randomgen cd ~/randomgen
创建一个文件名为
main.py
且包含以下 Python 代码的文本文件:如需支持依赖于 Flask 进行 HTTP 处理,请为 pip 软件包管理器创建一个文本文件。为该文本文件指定文件名
requirements.txt
并添加以下内容:为 Workflows 创建服务账号,以供使用:
export SERVICE_ACCOUNT=workflows-sa gcloud iam service-accounts create ${SERVICE_ACCOUNT}
如需允许服务账号调用经过身份验证的 Cloud Run 服务,请向 Workflows 服务账号授予
run.invoker
角色:gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com" \ --role "roles/run.invoker"
使用 HTTP 触发器部署函数,并允许未经身份验证的访问:
gcloud functions deploy randomgen-function \ --gen2 \ --runtime python310 \ --entry-point=randomgen \ --trigger-http \ --allow-unauthenticated
部署该函数可能需要几分钟的时间。或者,您也可以使用 Google Cloud 控制台中的 Cloud Run 函数界面来部署函数。
部署
randomgen
函数后,您可以确认httpsTrigger.url
属性:gcloud functions describe randomgen-function \ --gen2 \ --format="value(serviceConfig.uri)"
保存网址。 在后续练习中,您需要将它添加到工作流源文件中。
您可以通过以下 curl 命令来试用该函数:
curl $(gcloud functions describe randomgen-function \ --gen2 \ --format="value(serviceConfig.uri)")
系统随机会生成一个数字并返回。
部署第二项 Cloud Run 函数服务
收到 HTTP 请求后,此 HTTP 函数会从 JSON 正文中提取 input
,将此数字乘以 2,然后以 JSON 格式返回结果。
返回到您的主目录:
cd ~
创建名为
multiply
的目录并切换到该目录:mkdir ~/multiply cd ~/multiply
创建一个文件名为
main.py
且包含以下 Python 代码的文本文件:如需支持依赖于 Flask 进行 HTTP 处理,请为 pip 软件包管理器创建一个文本文件。为该文本文件指定文件名
requirements.txt
并添加以下内容:使用 HTTP 触发器部署函数,并允许未经身份验证的访问:
gcloud functions deploy multiply-function \ --gen2 \ --runtime python310 \ --entry-point=multiply \ --trigger-http \ --allow-unauthenticated
部署函数可能需要几分钟的时间。或者,您也可以使用 Google Cloud 控制台中的 Cloud Run 函数界面来部署函数。
部署
multiply
函数后,您可以确认httpsTrigger.url
属性:gcloud functions describe multiply-function \ --gen2\ --format="value(serviceConfig.uri)"
保存网址。 在后续练习中,您需要将它添加到工作流源文件中。
您可以通过以下 curl 命令来试用该函数:
curl -X POST MULTIPLY_FUNCTION_URL \ -H "Authorization: Bearer $(gcloud auth print-identity-token)" \ -H "Content-Type: application/json" \ -d '{"input": 5}'
系统应会返回数字 10。
在工作流中连接两项 Cloud Run 函数服务
工作流由一系列使用 Workflows 语法描述的步骤组成,该语法可以采用 YAML 或 JSON 格式编写。这是工作流的定义。如需了解详细说明,请参阅语法参考文档页面。
返回到您的主目录:
cd ~
创建一个文件名为
workflow.yaml
且包含以下内容的文本文件:- randomgen_function: call: http.get args: url: RANDOMGEN_FUNCTION_URL result: randomgen_result - multiply_function: call: http.post args: url: MULTIPLY_FUNCTION_URL body: input: ${randomgen_result.body.random} result: multiply_result - return_result: return: ${multiply_result}
- 将
RANDOMGEN_FUNCTION_URL
替换为您的randomgen
函数的网址。 - 将
MULTIPLY_FUNCTION_URL
替换为您的multiply
函数的网址。
此源文件会将两个 HTTP 函数关联在一起,并返回最终结果。
- 将
创建工作流后,可以进行部署,使其可以执行。
gcloud workflows deploy WORKFLOW_NAME \ --source=workflow.yaml
将
WORKFLOW_NAME
替换为您的工作流的名称。执行工作流:
gcloud workflows run WORKFLOW_NAME
执行是指单次运行工作流定义中包含的逻辑。所有工作流都会独立执行,并且 Workflows 的快速扩缩允许大量并发执行。
执行工作流后,输出应类似于以下内容:
result: '{"body":{"multiplied":120},"code":200,"headers":{"Alt-Svc":"h3-29=\":443\"; ... startTime: '2021-05-05T14:17:39.135251700Z' state: SUCCEEDED ...
在工作流中连接公共 REST 服务
更新现有工作流并连接可以用来对数学表达式求值的公共 REST API (math.js)。例如 curl https://api.mathjs.org/v4/?'expr=log(56)'
。
请注意,您已经部署了工作流,现在您可以通过 Google Cloud 控制台中的“工作流”页面对其进行修改。
修改工作流的源文件并将其替换为以下内容:
- randomgen_function: call: http.get args: url: RANDOMGEN_FUNCTION_URL result: randomgen_result - multiply_function: call: http.post args: url: MULTIPLY_FUNCTION_URL body: input: ${randomgen_result.body.random} result: multiply_result - log_function: call: http.get args: url: https://api.mathjs.org/v4/ query: expr: ${"log(" + string(multiply_result.body.multiplied) + ")"} result: log_result - return_result: return: ${log_result}
- 将
RANDOMGEN_FUNCTION_URL
替换为您的randomgen
函数的网址。 - 将
MULTIPLY_FUNCTION_URL
替换为您的multiply
函数的网址。
这会将外部 REST 服务与 Cloud Run 函数服务相关联,并返回最终结果。
- 将
部署修改后的工作流:
gcloud workflows deploy WORKFLOW_NAME \ --source=workflow.yaml
部署 Cloud Run 服务
部署 Cloud Run 服务,在收到 HTTP 请求后,该服务会从 JSON 正文中提取 input
,计算其 math.floor
,并返回结果。
创建名为
floor
的目录并切换到该目录:mkdir ~/floor cd ~/floor
创建一个文件名为
app.py
且包含以下 Python 代码的文本文件:在同一目录中,创建一个包含以下内容的
Dockerfile
:创建一个 Artifact Registry 标准制品库,您可以在其中存储您的 Docker 容器映像:
gcloud artifacts repositories create REPOSITORY \ --repository-format=docker \ --location=${REGION}
将
REPOSITORY
替换为制品库的唯一名称。构建容器映像:
export SERVICE_NAME=floor gcloud builds submit --tag ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}
将容器映像部署到 Cloud Run,确保其仅接受经过身份验证的调用:
gcloud run deploy ${SERVICE_NAME} \ --image ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}:latest \ --no-allow-unauthenticated
当您看到服务网址时,表示部署完成。 在更新工作流定义时,您需要指定该网址。
在工作流中连接 Cloud Run 服务
更新现有工作流并指定 Cloud Run 服务的网址。
修改工作流的源文件并将其替换为以下内容:
- randomgen_function: call: http.get args: url: RANDOMGEN_FUNCTION_URL result: randomgen_result - multiply_function: call: http.post args: url: MULTIPLY_FUNCTION_URL body: input: ${randomgen_result.body.random} result: multiply_result - log_function: call: http.get args: url: https://api.mathjs.org/v4/ query: expr: ${"log(" + string(multiply_result.body.multiplied) + ")"} result: log_result - floor_function: call: http.post args: url: CLOUD_RUN_SERVICE_URL auth: type: OIDC body: input: ${log_result.body} result: floor_result - create_output_map: assign: - outputMap: randomResult: ${randomgen_result} multiplyResult: ${multiply_result} logResult: ${log_result} floorResult: ${floor_result} - return_output: return: ${outputMap}
- 将
RANDOMGEN_FUNCTION_URL
替换为您的randomgen
函数的网址。 - 将
MULTIPLY_FUNCTION_URL
替换为您的multiply
函数的网址。 - 将
CLOUD_RUN_SERVICE_URL
替换为您的 Cloud Run 服务网址。
这将连接工作流中的 Cloud Run 服务。请注意,
auth
密钥可确保在调用 Cloud Run 服务时传递身份验证令牌。如需了解详情,请参阅通过工作流发出经过身份验证的请求。- 将
部署修改后的工作流:
gcloud workflows deploy WORKFLOW_NAME \ --source=workflow.yaml
执行最终工作流:
gcloud workflows run WORKFLOW_NAME
您应该会看到类似如下所示的输出:
result: '{"Floor":{"body":"4","code":200 ... "Log":{"body":"4.02535169073515","code":200 ... "Multiply":{"body":{"multiplied":56},"code":200 ... "Random":{"body":{"random":28},"code":200 ... startTime: '2023-11-13T21:22:56.782669001Z' state: SUCCEEDED
恭喜!您已部署并执行一个将一系列服务连接在一起的工作流。
如需使用表达式、条件跳转、Base64 编码或解码、子工作流等创建更复杂的工作流,请参阅工作流语法参考文档和标准库概览。
清理
如果您为本教程创建了一个新项目,请删除项目。 如果您使用的是现有项目,想要保留此项目且不保留本教程中添加的任何更改,请删除为教程创建的资源。
删除项目
为了避免产生费用,最简单的方法是删除您为本教程创建的项目。
要删除项目,请执行以下操作:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
删除教程资源
从 Artifact Registry 中删除容器映像。
移除您在教程设置过程中添加的 Google Cloud CLI 默认配置:
gcloud config unset functions/region gcloud config unset run/region gcloud config unset workflows/location gcloud config unset project