1. 簡介
Google Cloud Run 函式是事件導向的無伺服器運算平台,您可以使用 Cloud Run 函式編寫程式碼,不必擔心佈建資源或調整資源調度,以因應變更的需求。
Cloud Run 函式分為兩種類型:
- HTTP 函式會回應 HTTP 要求。
- 事件函式會在事件觸發時執行,例如訊息發布至 Cloud Pub/Sub 或檔案上傳至 Cloud Storage。
本程式碼研究室將逐步引導您使用 C# 建立自己的 Cloud Run 函式。具體來說,您將部署 C# 函式,回應來自各種 Google Cloud 來源的 HTTP 和 CloudEvents。
課程內容
- 適用於 .NET 的函式架構。
- 如何編寫 HTTP 函式。
- 如何編寫回應 Cloud Storage 事件的事件觸發函式。
- 如何編寫回應 Cloud Pub/Sub 事件的事件觸發函式。
- 如何編寫可回應任何類型事件的事件觸發函式。
2. 設定和需求
自助式環境設定
- 登入 Google Cloud 控制台,然後建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請務必建立帳戶。
- 「Project name」是這個專案參與者的顯示名稱。這是 Google API 不會使用的字元字串。您隨時可以更新。
- 專案 ID 在所有 Google Cloud 專案中不得重複,且無法變更 (設定後即無法變更)。Cloud 控制台會自動產生一個專屬字串,您通常不需要特別留意。在大多數程式碼研究室中,您都需要參照專案 ID (通常會標示為
PROJECT_ID
)。如果您不喜歡系統產生的 ID,可以隨機產生另一組 ID。或者,您也可以自行嘗試,看看是否可用。這項設定在這個步驟後即無法變更,並會在專案期間維持不變。 - 提醒您,有些 API 會使用第三個值,也就是「專案編號」。如要進一步瞭解這三個值,請參閱說明文件。
- 接下來,您需要在 Cloud 控制台中啟用帳單功能,才能使用 Cloud 資源/API。執行本程式碼研究室時,費用應該不會太高,甚至可能不收費。如要關閉資源,避免產生教學課程以外的費用,您可以刪除建立的資源,或刪除整個專案。Google Cloud 新使用者可享有 $300 美元的免費試用期。
啟動 Cloud Shell
雖然 Google Cloud 可透過筆記型電腦遠端操作,但在本程式碼研究室中,您將使用 Google Cloud Shell,這是在雲端運作的指令列環境。
在 Google Cloud 控制台中,按一下右上方工具列的 Cloud Shell 圖示:
佈建並連線至環境的作業需要一些時間才能完成。完成後,您應該會看到如下的畫面:
這個虛擬機器會載入您需要的所有開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提升網路效能和驗證功能。您可以在瀏覽器中完成本程式碼研究室的所有工作。您不需要安裝任何東西。
3. 事前準備
在 Cloud Shell 中執行下列指令,啟用必要服務:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ cloudfunctions.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com
接著,設定區域。
REGION=<YOUR_REGION>
在本程式碼研究室中,您將建立服務帳戶,並授予必要的 Eventarc 權限和 Cloud Run 叫用者角色,以便接收 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 事件接收者角色 (roles/eventarc.eventReceiver) 授予與 Eventarc 觸發條件相關聯的服務帳戶,讓觸發條件能夠接收事件供應者的事件。
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role=roles/eventarc.eventReceiver
接著,將 Cloud Run 叫用者角色授予服務帳戶,讓服務帳戶能夠叫用函式。
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role=roles/run.invoker
4. 適用於 .NET 的函式架構
Functions Framework for .NET 是 Google Cloud Functions 團隊推出的開放原始碼 FaaS (函式即服務) 架構,可用於編寫可移植的 .NET 函式。
Functions Framework 可讓您編寫簡易函式,並在許多不同環境中執行,包括:
- Google Cloud Run 函式
- 您的本機開發電腦
- Cloud Run 和 Cloud Run on GKE
- 以 Knative 為基礎的環境
在本程式碼研究室中,您將使用 .NET 專用 Functions Framework 和其範本,以 C# 語言建立及部署 Cloud Functions。
在 Cloud Shell 中執行下列指令,為 dotnet
安裝 Cloud 函式範本:
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
這會建立專案和 Function.cs
檔案,用於回應 HTTP 要求。
在 .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:
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
這會建立專案和 Function.cs
檔案,以回應 CloudEvent
要求。並將 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
您將建立並部署回應 Cloud Pub/Sub 事件的 CloudEvent 函式。
首先,建立會發出事件的 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
這會建立專案和 Function.cs
檔案,以回應 CloudEvent
要求。預設也會將 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 函式 - 未指定類型
如果您正在測試 CloudEvent,但尚未有要提交的酬載資料模型,或是希望函式能夠處理任何 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. 恭喜!
恭喜您完成程式碼研究室!
涵蓋內容
- 適用於 .NET 的函式架構。
- 如何編寫 HTTP Cloud 函式。
- 如何編寫可回應 Cloud Storage 事件的 CloudEvent 函式。
- 如何編寫回應 Cloud Pub/Sub 事件的 CloudEvent 函式。
- 如何編寫可回應任何類型事件的 CloudEvent 函式。