关于此 Codelab
1. 简介
Google Cloud Run 函数是一个事件驱动型无服务器计算平台,借助 Cloud Run 函数,您可以编写代码,而无需担心预配资源或扩缩以应对不断变化的要求。
Cloud Run 函数有两种类型:
- HTTP 函数会响应 HTTP 请求。
- 事件函数由事件触发,例如有消息发布到 Cloud Pub/Sub 或有文件上传到 Cloud Storage。
本 Codelab 将引导您使用 C# 创建自己的 Cloud Run 函数。具体而言,您将部署 C# 函数来响应来自各种 Google Cloud 来源的 HTTP 和 CloudEvent。
学习内容
- .NET 版 Functions 框架。
- 如何编写 HTTP 函数。
- 如何编写响应 Cloud Storage 事件的事件触发型函数。
- 如何编写响应 Cloud Pub/Sub 事件的事件触发型函数。
- 如何编写响应任何类型事件的事件触发型函数。
2. 设置和要求
自定进度的环境设置
- 登录 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
虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。
在 Google Cloud 控制台 中,点击右上角工具栏中的 Cloud Shell 图标:
预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:
这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5 GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。您在此 Codelab 中的所有工作都可以在浏览器中完成。您无需安装任何程序。
3. 准备工作
在 Cloud Shell 中,运行以下命令以启用所需的服务:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ cloudfunctions.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com
接下来,设置您的地区。
REGION=<YOUR_REGION>
在本 Codelab 中,您将创建一个具有所需 Eventarc 权限和 Cloud Run Invoker 角色的服务账号,以便从 Cloud Storage 接收事件并调用 Cloud Run 函数。
首先,创建服务账号。
PROJECT_ID=$(gcloud config get-value core/project) PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)') SERVICE_ACCOUNT="cloud-run-functions" SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com gcloud iam service-accounts create $SERVICE_ACCOUNT \ --display-name="Cloud Run functions Eventarc service account"
接下来,将项目的 Eventarc Event Receiver 角色 (roles/eventarc.eventReceiver) 授予与您的 Eventarc 触发器关联的服务账号,以便该触发器可以接收来自事件提供程序的事件。
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role=roles/eventarc.eventReceiver
然后,向服务账号授予 Cloud Run Invoker 角色,以便其可以调用函数。
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role=roles/run.invoker
4. .NET 版 Functions 框架
适用于 .NET 的 Functions 框架是一个开源 FaaS(函数即服务)框架,用于编写可移植的 .NET 函数。此框架由 Google Cloud Functions 团队提供。
借助 Cloud Functions 框架,您可以编写在许多不同环境中运行的轻量级函数,这些环境包括:
- Google Cloud Run functions
- 您的本地开发机器
- Cloud Run 和 Cloud Run on GKE
- 基于 Knative 的环境
在本 Codelab 中,您将使用适用于 .NET 的 Functions 框架及其模板,以 C# 语言创建和部署 Cloud Functions 函数。
在 Cloud Shell 中,运行以下命令以安装适用于 dotnet
的 Cloud Functions 模板:
dotnet new install Google.Cloud.Functions.Templates
这会为 dotnet
安装 3 个模板。每个模板均提供 C#、F# 和 VB 版本(但您在本实验中只会使用 C#)。您可以通过运行以下命令来验证模板是否已安装:
dotnet new list Templates Short Name ----------------------------------------------------------------------- Google Cloud Functions CloudEvent Function gcf-event Google Cloud Functions CloudEvent Function (Untyped) gcf-untyped-event Google Cloud Functions HttpFunction gcf-http
5. HTTP 函数
您将创建和部署一个 HTTP 函数来响应 HTTP 请求。
使用 gcf-http
模板创建 HTTP 函数:
mkdir HelloHttp cd HelloHttp dotnet new gcf-http
这会创建一个项目和一个用于响应 HTTP 请求的 Function.cs
文件。
在 .csproj
文件中将目标框架更改为 net8.0
:
<TargetFramework>net8.0</TargetFramework>
如需将 Cloud Run 函数直接部署到 Cloud Run,请运行以下命令:
gcloud beta run deploy hello-http-function \ --source . \ --function HelloHttp.Function \ --base-image dotnet8 \ --region $REGION \ --allow-unauthenticated
如果您想以 Cloud Functions (第 2 代) 的形式进行部署,请使用以下命令:
gcloud functions deploy hello-http-function \ --allow-unauthenticated \ --entry-point HelloHttp.Function \ --gen2 \ --region $REGION \ --runtime dotnet8 \ --trigger-http
函数部署完毕后,您可以使用以下 curl 命令调用该函数:
SERVICE_URL=$(gcloud run services describe hello-http-function --platform managed --region $REGION --format 'value(status.url)') curl $SERVICE_URL
6. CloudEvent 函数 - GCS
您将创建并部署一个 CloudEvent 函数来响应 Google Cloud Storage (GCS) 事件。
首先,创建一个 Cloud Storage 存储分区。您稍后将从该存储分区监听事件:
BUCKET_NAME="cloud-functions-bucket-${PROJECT_ID}" gsutil mb -l us-central1 gs://${BUCKET_NAME}
使用 gcf-event
模板创建 CloudEvent 函数:
cd .. mkdir HelloGcs cd HelloGcs dotnet new gcf-event
这会创建一个项目和一个响应 CloudEvent
请求的 Function.cs
文件。它还会将 CloudEvent
的数据解析为 StorageObjectData
。
在 .csproj
文件中将目标框架更改为 net8.0
:
<TargetFramework>net8.0</TargetFramework>
如需将 Cloud Run 函数直接部署到 Cloud Run,您需要先部署该函数,然后为其创建触发器。
gcloud beta run deploy hello-gcs-function \ --source . \ --function HelloGcs.Function \ --region $REGION \ --base-image dotnet8 \ --no-allow-unauthenticated
现在,为 Cloud Run 函数创建触发器
BUCKET_REGION=$REGION gcloud eventarc triggers create hello-gcs-function-trigger \ --location=$REGION \ --destination-run-service=hello-gcs-function \ --destination-run-region=$BUCKET_REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET_NAME" \ --service-account=$SERVICE_ACCOUNT_ADDRESS
如果您希望以 Cloud Functions 第 2 代函数的形式进行部署,可以使用以下命令使用 trigger-event
和 trigger-resource
标志部署函数:
gcloud functions deploy hello-gcs-function \ --allow-unauthenticated \ --entry-point HelloGcs.Function \ --gen2 \ --region $REGION \ --runtime dotnet8 \ --trigger-event google.storage.object.finalize \ --trigger-resource ${BUCKET_NAME} \ --service-account=$SERVICE_ACCOUNT_ADDRESS
几分钟后,该函数应会显示在 Cloud 控制台中:
通过将文件上传到存储分区来触发函数:
echo "Hello from Storage" > random.txt gsutil cp random.txt gs://${BUCKET_NAME}
通过查看日志,验证函数是否已触发:
对于 Cloud Run 函数,您可以运行以下命令:
gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json
对于第 2 代函数,您可以运行以下命令:
gcloud functions logs read hello-gcs-function \ --gen2 \ --region us-central1
7. CloudEvent 函数 - Pub/Sub
您将创建并部署一个 CloudEvent 函数来响应 Cloud Pub/Sub 事件。
首先,创建一个将发出事件的 Cloud Pub/Sub 主题:
TOPIC_NAME=cloud-functions-topic gcloud pubsub topics create ${TOPIC_NAME}
使用 gcf-event
模板创建 CloudEvent 函数:
cd .. mkdir HelloPubSub cd HelloPubSub dotnet new gcf-event
这会创建一个项目和一个响应 CloudEvent
请求的 Function.cs
文件。它还会默认将 CloudEvent
的数据解析为 StorageObjectData
。
在 .csproj
文件中将目标框架更改为 net8.0
:
<TargetFramework>net8.0</TargetFramework>
将 StorageObjectData
更改为 MessagePublishedData
以解析 Pub/Sub 消息。将 Google.Events.Protobuf.Cloud.Storage.V1
更改为 Google.Events.Protobuf.Cloud.PubSub.V1
。
最后,您的函数应如下所示:
using CloudNative.CloudEvents; using Google.Cloud.Functions.Framework; using Google.Events.Protobuf.Cloud.PubSub.V1; using System; using System.Threading; using System.Threading.Tasks; namespace HelloPubSub; public class Function : ICloudEventFunction<MessagePublishedData> { public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken) { var nameFromMessage = data.Message?.TextData; var name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage; Console.WriteLine($"Hello {name}"); return Task.CompletedTask; } }
如需将 Cloud Run 函数直接部署到 Cloud Run,您需要先部署该函数,然后为其创建触发器。
gcloud beta run deploy hello-pubsub-function \ --source . \ --function HelloPubSub.Function \ --region $REGION \ --base-image dotnet8 \ --no-allow-unauthenticated \ --service-account=$SERVICE_ACCOUNT_ADDRESS
现在,为 Cloud Run 函数创建触发器
gcloud eventarc triggers create my-pubsub-trigger \ --location=$REGION \ --service-account=$SERVICE_ACCOUNT_ADDRESS \ --destination-run-service=hello-pubsub-function \ --destination-run-region=$REGION \ --destination-run-path="/" \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --transport-topic=projects/$PROJECT_ID/topics/$TOPIC_NAME
如果您希望以 Cloud Functions 第 2 代函数的形式进行部署,可以使用以下命令使用 trigger-topic
标志部署函数:
gcloud functions deploy hello-pubsub-function \ --allow-unauthenticated \ --entry-point HelloPubSub.Function \ --gen2 \ --region us-central1 \ --runtime dotnet8 \ --trigger-topic ${TOPIC_NAME}
几分钟后,该函数应会显示在 Cloud 控制台中:
向以下主题发布消息以触发函数:
gcloud pubsub topics publish ${TOPIC_NAME} --message="World"
通过查看日志,验证函数是否已触发。
对于 Cloud Run 函数,您可以运行以下命令:
gcloud logging read "resource.labels.service_name=hello-pubsub-function AND textPayload: World" --format=json
对于第 2 代函数,您可以运行以下命令:
gcloud functions logs read hello-pubsub-function \ --gen2 \ --region us-central1
8. CloudEvent 函数 - 无类型
如果您正在实验 CloudEvents,并且尚未确定要提交的数据载荷模型,或者希望函数能够处理任何 Cloud Event,则可以使用无类型的 CloudEvent 函数。
使用 gcf-untyped-event
模板创建 CloudEvent 函数:
cd .. mkdir HelloUntyped cd HelloUntyped dotnet new gcf-untyped-event
这会创建一个项目和一个 Function.cs
文件,用于响应 CloudEvent
请求,而不会尝试解析 CloudEvent
的数据。
在 .csproj
文件中将目标框架更改为 net8.0
:
<TargetFramework>net8.0</TargetFramework>
如需将 Cloud Run 函数直接部署到 Cloud Run,您需要先部署该函数,然后为其创建触发器。
gcloud beta run deploy hello-untyped-function \ --source . \ --function HelloUntyped.Function \ --region $REGION \ --base-image dotnet8 \ --no-allow-unauthenticated
现在,为 Cloud Run 函数创建触发器
BUCKET_REGION=$REGION gcloud eventarc triggers create hello-untyped-function-trigger \ --location=$REGION \ --destination-run-service=hello-untyped-function \ --destination-run-region=$BUCKET_REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET_NAME" \ --service-account=$SERVICE_ACCOUNT_ADDRESS
如果您希望以 Cloud Functions 第 2 代函数的形式进行部署,可以使用以下命令使用 trigger-event
和 trigger-resource
标志部署函数:
gcloud functions deploy hello-untyped-function \ --allow-unauthenticated \ --entry-point HelloUntyped.Function \ --gen2 \ --region us-central1 \ --runtime dotnet8 \ --trigger-event google.storage.object.finalize \ --trigger-resource ${BUCKET_NAME}
当有文件上传到存储分区时,该函数将触发。
几分钟后,该函数应会显示在 Cloud 控制台中:
通过将文件上传到存储分区来触发函数:
echo "Hello from Storage" > random.txt gsutil cp random.txt gs://${BUCKET_NAME}
通过查看日志,验证函数是否已触发。
对于 Cloud Run 函数,您可以运行以下命令:
gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json
对于第 2 代函数,您可以运行以下命令:
gcloud functions logs read hello-untyped-function \ --gen2 \ --region us-central1
9. 恭喜!
恭喜您完成此 Codelab。
所学内容
- .NET 版 Functions 框架。
- 如何编写 HTTP Cloud Functions 函数。
- 如何编写响应 Cloud Storage 事件的 CloudEvent 函数。
- 如何编写响应 Cloud Pub/Sub 事件的 CloudEvent 函数。
- 如何编写响应任何类型事件的 CloudEvent 函数。