1. 简介
Eventarc 可让您轻松地将 Cloud Run 服务与各种来源的事件进行关联。它允许您构建微服务松散耦合和分布的事件驱动型架构。它会为您处理事件提取、传送、安全性、授权以及错误处理。
工作流是一个全代管式编排平台,按照您指定的顺序执行服务:工作流。这些工作流可以结合使用 Cloud Run 或 Cloud Functions 托管的服务、Cloud Vision AI 和 BigQuery 等 Google Cloud 服务以及任何基于 HTTP 的 API。
在此 Codelab 中,您将构建一个事件驱动型微服务编排系统来处理图片。您将使用 Workflows 来编排 4 张图片处理 Cloud Functions 的顺序、输入和输出。然后,您将让编排通过与 Eventarc 的松散耦合的方式响应 Cloud Storage 事件。
最后,您将得到一个灵活但结构化的无服务器架构来处理图片。
学习内容
- Eventarc 和工作流概览
- 如何部署 Cloud Functions 服务
- 如何使用 Workflows 编排服务
- 如何让 Workflows 使用 Eventarc 响应 Cloud Storage 事件
2. 设置和要求
兑换积分
转到 https://gcpcredits.com/io2022 并点击“点击此处访问您的赠金”按钮:
在后续对话框中,点击“接受并继续”按钮以接受服务条款:
接受服务条款后,您将被重定向到一个结算摘要页,其右下角会出现一个面板,如下所示:
最后,当您创建第一个项目时,系统会显示一个对话框,您可以在其中为项目分配结算帐号。选择与免费赠金相关联的结算帐号,然后点击“创建”按钮:
总而言之,您现在拥有结算帐号和项目,这两个实体相关联,因此您今天的 Codelab 中所做的任何工作都将获得您的免费赠金**。**
自定进度的环境设置
- 登录 Google Cloud Console,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 帐号,则必须创建一个。
- 项目名称是此项目参与者的显示名。它是 Google API 不使用的字符串,并且您可以随时对其进行更新。
- 项目 ID 在所有 Google Cloud 项目中必须是唯一的,并且不可变(一经设置便无法更改)。Cloud Console 会自动生成一个唯一字符串;通常您并不在意它是什么。在大多数 Codelab 中,您都需要引用项目 ID(它通常标识为
PROJECT_ID
),因此,如果您不喜欢它,请再生成一个随机 ID,或者您也可以尝试自己创建一个,看看可用。然后,项目创建后会处于“冻结”状态。 - 第三个值是一些项目所用的项目编号。如需详细了解所有这三个值,请参阅文档。
- 接下来,您需要在 Cloud Console 中启用结算功能,才能使用 Cloud 资源/API。此 Codelab 的运行费用应该不会太多。要关闭资源以免产生超出本教程范围的费用,请按照 Codelab 末尾提供的任何“清理”说明操作。Google Cloud 的新用户有资格参与 $300 USD 免费试用计划。
启动 Cloud Shell
虽然 Google Cloud 可以从笔记本电脑远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,它是在云端运行的命令行环境。
在 Google Cloud Console 中,点击右上角的工具栏上的 Cloud Shell 图标:
预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:
这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并在 Google Cloud 上运行,大大增强了网络性能和身份验证。只需一个浏览器,即可完成本实验中的所有工作。
设置 gcloud
在 Cloud Shell 中,设置项目 ID 和要在其中部署应用的应用的区域。将它们保存为 PROJECT_ID
和 REGION
变量。如需了解可用区域,请参阅 Cloud Functions 位置。
PROJECT_ID=[YOUR-PROJECT-ID] REGION=[YOUR-REGION] gcloud config set core/project $PROJECT_ID gcloud config set functions/region $REGION
启用服务
启用所有必要的服务:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ cloudfunctions.googleapis.com \ eventarc.googleapis.com \ vision.googleapis.com \ workflows.googleapis.com \ workflowexecutions.googleapis.com
获取源代码
该应用的源代码位于 eventarc-samples 代码库的 processing-pipelines
文件夹中。
克隆代码库:
git clone https://github.com/GoogleCloudPlatform/eventarc-samples.git
转到 eventarc-samples/processing-pipelines
文件夹:
cd eventarc-samples/processing-pipelines
3.架构概览
该应用的架构如下:
- 图片会保存到生成 Cloud Storage 创建事件的输入存储分区中。
- Eventarc 通过 Cloud Storage 触发器读取 Cloud Storage 创建事件,并将其作为 CloudEvent 传递到工作流。
- 在工作流程的第一步中,Cloud Functions 服务 Filter 使用 Vision API 确定图片是否安全。如果图片安全,Workflows 会继续执行后续步骤。
- 在工作流的第二步,Cloud Functions 服务 Labeler 会使用 Vision API 提取图片的标签,并将标签保存到输出存储分区。
- 第三步,Resizer(另一个 Cloud Functions 函数服务)使用 ImageSharp 调整图片大小,并将调整后的图片保存到输出存储分区。
- 在最后一步中,Watermarker(另一个 Cloud Functions 函数服务)使用 ImageSharp 将标签添加水印添加到调整后的图片,并将图片保存到输出存储分区。
该应用由 Cloud Storage 事件触发,因此是由事件驱动的。图片处理在工作流中进行,因此是一种编排。最终,它是一个由事件驱动的编排,用于处理灵活但结构化的无服务器架构来处理图片。
4.创建存储分区
为用户创建一个上传存储分区,将图片上传到其中;为图片处理流水线创建一个输出存储分区,以保存处理后的图片。
在 Cloud Shell 中运行下面的命令:
BUCKET1=$PROJECT_ID-images-input BUCKET2=$PROJECT_ID-images-output gsutil mb -l $REGION gs://$BUCKET1 gsutil mb -l $REGION gs://$BUCKET2
5. 部署过滤器服务
首先,部署第一个服务。此 Cloud Functions 服务会接收存储分区和文件信息,确定该图片是否通过 Vision API 安全返回结果。
在顶级 processing-pipelines
文件夹中,部署该服务:
SERVICE_NAME=filter gcloud functions deploy $SERVICE_NAME \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --entry-point Filter.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v3/filter/csharp
部署函数后,在变量中设置服务网址,稍后我们将需要使用该网址:
FILTER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')
6.部署标签添加者服务
第二个 Cloud Functions 服务接收存储分区和文件信息,使用 Vision API 提取图片的标签,然后将这些标签保存到输出存储分区。
在顶级 processing-pipelines
文件夹中,部署该服务:
SERVICE_NAME=labeler gcloud functions deploy $SERVICE_NAME \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Labeler.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/labeler/csharp
部署函数后,在变量中设置服务网址,稍后我们将需要使用该网址:
LABELER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')
7. 部署大小调整器服务
此 Cloud Functions 服务接收存储分区和文件信息,使用 ImageSharp 调整图片大小,并将图片保存到输出存储分区。
在顶级 processing-pipelines
文件夹中,部署该服务:
SERVICE_NAME=resizer gcloud functions deploy $SERVICE_NAME \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Resizer.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/resizer/csharp
部署函数后,在变量中设置服务网址,稍后我们将需要使用该网址:
RESIZER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')
8. 部署水印功能
此 Cloud Functions 服务接收存储分区、文件和标签信息,读取文件,使用 ImageSharp 将标签作为水印添加到图片中,然后将图片保存到输出存储分区。
在顶级 processing-pipelines
文件夹中,部署该服务:
SERVICE_NAME=watermarker gcloud functions deploy $SERVICE_NAME \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Watermarker.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/watermarker/csharp
部署函数后,在变量中设置服务网址,稍后我们将需要使用该网址:
WATERMARKER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')
此时,应部署并运行所有四个 Cloud Functions 函数:
9. 定义和部署工作流
使用 Workflows 将过滤器、标签添加者、调整大小器和水印功能整合到一个工作流中。工作流会按照我们定义的参数顺序调用这些服务。
定义
工作流接收 CloudEvent 作为参数。在我们创建触发器后,这将来自 Eventarc。在前两步中,Workflows 记录事件,并从事件中提取存储分区和文件信息:
main: params: [event] steps: - log_event: call: sys.log args: text: ${event} severity: INFO - extract_bucket_and_file: assign: - bucket: ${event.data.bucket} - file: ${event.data.name}
在 filter
步骤中,Workflows 会调用我们之前部署的过滤器服务。然后,它会记录并检查文件安全性:
- filter: call: http.post args: url: FILTER_URL # TODO: Replace auth: type: OIDC body: bucket: ${bucket} file: ${file} result: filterResponse - log_safety: call: sys.log args: text: ${filterResponse.body.safe} severity: INFO - check_safety: switch: - condition: ${filterResponse.body.safe == true} next: label next: end
在 label
步骤中,Workflows 会调用标签添加者服务并捕获响应(前 3 个标签):
- label: call: http.post args: url: LABELER_URL # TODO: Replace auth: type: OIDC body: bucket: ${bucket} file: ${file} result: labelResponse
在 resize
步骤中,Workflows 会调用调整器服务并捕获响应(调整后的图片的存储分区和文件):
- resize: call: http.post args: url: RESIZER_URL # TODO: Replace auth: type: OIDC body: bucket: ${bucket} file: ${file} result: resizeResponse
在 watermark
步骤中,Workflows 会使用调整后的图片和标签调用水印标记服务,并捕获结果(调整后大小和添加水印的图片):
- watermark: call: http.post args: url: WATERMARKER_URL # TODO: Replace auth: type: OIDC body: bucket: ${resizeResponse.body.bucket} file: ${resizeResponse.body.file} labels: ${labelResponse.body.labels} result: watermarkResponse
在 final
步骤中,Workflows 会返回标记器、调整大小器和水印器服务的 HTTP 状态代码:
- final: return: label: ${labelResponse.code} resize: ${resizeResponse.code} watermark: ${watermarkResponse.code}
部署
在部署工作流之前,请确保手动或使用 sed
将服务网址替换为已部署函数的网址:
在顶级 processing-pipelines
文件夹内,转到 workflows.yaml
文件所在的 image-v3
文件夹:
cd image-v3/
运行 sed
以将占位符网址替换为已部署服务的实际网址:
sed -i -e "s|FILTER_URL|${FILTER_URL}|" workflow.yaml sed -i -e "s|LABELER_URL|${LABELER_URL}|" workflow.yaml sed -i -e "s|RESIZER_URL|${RESIZER_URL}|" workflow.yaml sed -i -e "s|WATERMARKER_URL|${WATERMARKER_URL}|" workflow.yaml
部署工作流:
WORKFLOW_NAME=image-processing gcloud workflows deploy $WORKFLOW_NAME \ --source=workflow.yaml \ --location=$REGION
几秒钟后,您应该会看到控制台中部署的工作流:
10. 创建触发器
现在工作流已部署完毕,最后一步是使用 Eventarc 触发器将其连接到 Cloud Storage 事件。
一次性设置
触发器将使用默认的计算服务帐号。确保它具有 eventarc.eventReceiver
角色:
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)') gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role roles/eventarc.eventReceiver
将 pubsub.publisher
角色授予 Cloud Storage 服务帐号。以下是 Eventarc 的 Cloud Storage 触发器所需的属性:
SERVICE_ACCOUNT="$(gsutil kms serviceaccount -p $PROJECT_NUMBER)" gcloud projects add-iam-policy-binding $PROJECT_NUMBER \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
创建
运行以下命令以创建触发器。此触发器会过滤来自 Cloud Storage 输入存储分区的新文件创建事件,并将其传递到我们之前定义的工作流:
TRIGGER_NAME=trigger-$WORKFLOW_NAME gcloud eventarc triggers create $TRIGGER_NAME \ --location=$REGION \ --destination-workflow=$WORKFLOW_NAME \ --destination-workflow-location=$REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET1" \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
您可以在 Cloud Console 的 Eventarc 部分看到触发器已创建并准备就绪:
11. 测试流水线
图片处理流水线已准备好从 Cloud Storage 接收事件。如需测试流水线,请将图片上传到输入存储分区:
gsutil cp beach.jpg gs://$BUCKET1
上传照片后,您应该可以看到处于活跃状态的工作流执行:
大约一分钟后,您应该会看到执行成功。您还可以看到工作流的输入和输出:
如果您列出输出存储分区的内容,应该会看到调整后的图片、调整后的水印图片以及图片的标签:
gsutil ls gs://$BUCKET2 gs://$PROJECT_ID-images-output/beach-400x400-watermark.jpeg gs://$PROJECT_ID-images-output/beach-400x400.png gs://$PROJECT_ID-images-output/beach-labels.txt
如需仔细检查,您可以打开调整大小后带有水印的图片以查看结果:
12. 恭喜
恭喜,您已完成此 Codelab!
所学内容
- Eventarc 和工作流概览
- 如何部署 Cloud Functions 服务
- 如何使用 Workflows 编排服务
- 如何让 Workflows 使用 Eventarc 响应 Cloud Storage 事件