Google Cloud Functions ב-C#

Google Cloud Functions ב-C#

מידע על Codelab זה

subjectהעדכון האחרון: אוק׳ 7, 2024
account_circleנכתב על ידי Mete Atamel

1.‏ מבוא

פונקציות של Google Cloud Run הן פלטפורמת מחשוב ללא שרת (serverless) מבוססת-אירועים. פונקציות של Cloud Run מאפשרות לכם לכתוב את הקוד בלי לדאוג להקצאת משאבים או להתאמה לעומס כדי לעמוד בדרישות המשתנות.

יש שני סוגים של פונקציות Cloud Run:

  • פונקציות HTTP מגיבות לבקשות HTTP.
  • פונקציות של אירועים מופעלות על ידי אירועים, כמו פרסום הודעה ב-Cloud Pub/Sub או העלאת קובץ ל-Cloud Storage.

efb3268e3b74ed4f.png

ב-codelab הזה תלמדו איך ליצור פונקציות Cloud Run משלכם ב-C#. באופן ספציפי יותר, תפרסו פונקציות C# שמגיבות ל-HTTP ול-CloudEvents ממקורות שונים ב-Google Cloud.

מה תלמדו

  • Functions Framework for ‎ .NET.
  • איך כותבים פונקציית HTTP.
  • איך כותבים פונקציה שמופעל על ידי אירוע ומגיבה לאירועים ב-Cloud Storage.
  • איך כותבים פונקציה שמופעל על ידי אירוע ומגיבה לאירועים ב-Cloud Pub/Sub.
  • איך לכתוב פונקציה שמופעל על ידי אירוע ומגיבה לכל סוג של אירוע.

2.‏ הגדרה ודרישות

הגדרת סביבה בקצב אישי

  1. נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או משתמשים מחדש בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • שם הפרויקט הוא השם המוצג של המשתתפים בפרויקט. זוהי מחרוזת תווים שלא משמשת את Google APIs. אפשר לעדכן את המיקום הזה בכל שלב.
  • מזהה הפרויקט צריך להיות ייחודי בכל הפרויקטים ב-Google Cloud, והוא לא ניתן לשינוי (אי אפשר לשנות אותו אחרי שמגדירים אותו). מסוף Cloud יוצר מחרוזת ייחודית באופן אוטומטי. בדרך כלל לא משנה מה המחרוזת הזו. ברוב ה-codelabs תצטרכו להפנות למזהה הפרויקט (בדרך כלל הוא מזוהה בתור PROJECT_ID). אם המזהה שנוצר לא מוצא חן בעיניכם, תוכלו ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות שם משלכם ולבדוק אם הוא זמין. לא ניתן לשנות את השם אחרי השלב הזה, והוא יישאר למשך כל תקופת הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי העזרה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים או ב-API של Cloud. השלמת הקודלאב הזה לא אמורה לעלות הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים אחרי סיום המדריך, אפשר למחוק את המשאבים שיצרתם או למחוק את הפרויקט כולו. משתמשים חדשים ב-Google Cloud זכאים להשתתף בתוכנית תקופת ניסיון בחינם בסך 300$.

הפעלת Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל בסדנת הקוד הזו נשתמש ב-Google Cloud Shell, סביבת שורת פקודה שפועלת ב-Cloud.

במסוף Google Cloud, לוחצים על סמל Cloud Shell בסרגל הכלים שבפינה הימנית העליונה:

55efc1aaa7a4d3ad.png

תהליך ההקצאה והחיבור לסביבה אמור להימשך רק כמה רגעים. בסיום, אמור להופיע משהו כזה:

7ffe5cbb04455448.png

המכונה הווירטואלית הזו כוללת את כל הכלים הדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-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 את התפקיד 'מקבל אירועים' ב-Eventarc (roles/eventarc.eventReceiver) בפרויקט, כדי שהטריגר יוכל לקבל אירועים מספקי אירועים.

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.‏ Functions Framework for ‎ .NET

Functions Framework for ‎ .NET היא מסגרת FaaS (Function as a Service) בקוד פתוח לכתיבה של פונקציות ‎ .NET ניידות – שפותחה על ידי צוות Google Cloud Functions.

באמצעות Functions Framework אפשר לכתוב פונקציות קלילות שפועלות בסביבות רבות ושונות, כולל:

  • פונקציות של Google Cloud Run
  • המכונה המקומית לפיתוח
  • Cloud Run ו-Cloud Run ב-GKE
  • סביבות מבוססות-Knative

ב-codelab הזה תלמדו איך להשתמש ב-Functions Framework for ‎ .NET ובתבניות שלו כדי ליצור ולפרוס פונקציות של Cloud Functions ב-C#‎.

ב-Cloud Shell, מריצים את הפקודה הבאה כדי להתקין תבניות של Cloud Functions עבור dotnet:

dotnet new install Google.Cloud.Functions.Templates

הפקודה הזו מתקינה 3 תבניות עבור dotnet. כל תבנית זמינה ב-C#, ב-F# וב-VB (אבל בשיעור ה-Lab הזה תשתמשו רק ב-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.

יוצרים פונקציית HTTP באמצעות התבנית gcf-http:

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

הפקודה הזו יוצרת פרויקט וקובץ Function.cs שמגיב לבקשות HTTP.

משנים את מסגרת היעד ל-net8.0 בקובץ .csproj:

<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 מדור שני, משתמשים בפקודה הבאה:

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}

יוצרים פונקציית CloudEvent באמצעות התבנית gcf-event:

cd ..
mkdir HelloGcs
cd HelloGcs
dotnet new gcf-event

הפקודה הזו יוצרת פרויקט וקובץ Function.cs שתגובה לבקשות CloudEvent. הוא גם מנתח את הנתונים של CloudEvent ל-StorageObjectData.

משנים את מסגרת היעד ל-net8.0 בקובץ .csproj:

<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 דור שני, תוכלו להשתמש בפקודה הבאה כדי לפרוס את הפונקציה באמצעות הדגלים 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:

c28654d74bb31420.png

מפעילים את הפונקציה על ידי העלאת קובץ לקטגוריית האחסון:

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

בפונקציה מדור שני, אפשר להריץ את הפקודה הבאה:

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}

יוצרים פונקציית CloudEvent באמצעות התבנית gcf-event:

cd ..
mkdir HelloPubSub
cd HelloPubSub
dotnet new gcf-event

הפקודה הזו יוצרת פרויקט וקובץ Function.cs שתגובה לבקשות CloudEvent. בנוסף, המערכת מפענחת את הנתונים של CloudEvent ל-StorageObjectData כברירת מחדל.

משנים את מסגרת היעד ל-net8.0 בקובץ .csproj:

<TargetFramework>net8.0</TargetFramework>

כדי לנתח הודעות Pub/Sub, משנים את הערך של StorageObjectData ל-MessagePublishedData. משנים את 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 מדור שני, תוכלו להשתמש בפקודה הבאה כדי לפרוס את הפונקציה באמצעות הדגל 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:

3443808da7caf3bc.png

מפעילים את הפונקציה על ידי פרסום הודעה בנושא:

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

בפונקציה מדור שני, אפשר להריץ את הפקודה הבאה:

gcloud functions logs read hello-pubsub-function \
    --gen2 \
    --region us-central1

8.‏ פונקציית CloudEvent – ללא סיווג

אם אתם בודקים את CloudEvents ואין לכם עדיין מודל נתונים של עומס עבודה שתרצו להתחייב אליו, או אם אתם רוצים שהפונקציה תוכל לטפל בכל אירוע Cloud, תוכלו להשתמש בפונקציית CloudEvent ללא סיווג.

יוצרים פונקציית CloudEvent באמצעות התבנית gcf-untyped-event:

cd ..
mkdir HelloUntyped
cd HelloUntyped
dotnet new gcf-untyped-event

הפקודה הזו יוצרת פרויקט וקובץ Function.cs שתגובה לבקשות CloudEvent בלי לנסות לנתח את הנתונים של ה-CloudEvent.

משנים את מסגרת היעד ל-net8.0 בקובץ .csproj:

<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 דור שני, תוכלו להשתמש בפקודה הבאה כדי לפרוס את הפונקציה באמצעות הדגלים 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:

afe56530826787c6.png

מפעילים את הפונקציה על ידי העלאת קובץ לקטגוריית האחסון:

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

בפונקציה מדור שני, אפשר להריץ את הפקודה הבאה:

gcloud functions logs read hello-untyped-function \
    --gen2 \
    --region us-central1

9.‏ מעולה!

כל הכבוד על השלמת ה-Codelab.

מה עסקנו בו

  • Functions Framework for ‎ .NET.
  • איך כותבים פונקציית Cloud HTTP.
  • איך כותבים פונקציית CloudEvent שמגיבה לאירועים ב-Cloud Storage.
  • איך כותבים פונקציית CloudEvent שמגיבה לאירועים ב-Cloud Pub/Sub.
  • איך כותבים פונקציית CloudEvent שמגיבה לכל סוג של אירוע.