Google Cloud Functions in C#

1. Einführung

Google Cloud Run Functions ist eine ereignisgesteuerte serverlose Computing-Plattform. Mit Cloud Run Functions können Sie Code schreiben, ohne sich um die Bereitstellung von Ressourcen oder die Skalierung zur Bewältigung sich ändernder Anforderungen kümmern zu müssen.

Es gibt zwei Arten von Cloud Run-Funktionen:

  • HTTP-Funktionen reagieren auf HTTP-Anfragen.
  • Ereignisfunktionen werden durch Ereignisse ausgelöst, z. B. wenn eine Nachricht in Cloud Pub/Sub veröffentlicht oder eine Datei in Cloud Storage hochgeladen wird.

efb3268e3b74ed4f.png

In diesem Codelab erfahren Sie, wie Sie Ihre eigenen Cloud Run Functions in C# erstellen. Genauer gesagt stellen Sie C#-Funktionen bereit, die auf HTTP- und CloudEvents aus verschiedenen Google Cloud-Quellen reagieren.

Lerninhalte

  • Functions Framework für .NET.
  • HTTP-Funktion schreiben
  • Eine ereignisgesteuerte Funktion schreiben, die auf Cloud Storage-Ereignisse reagiert
  • Informationen zum Schreiben einer ereignisgesteuerten Funktion, die auf Cloud Pub/Sub-Ereignisse reagiert.
  • So schreiben Sie eine ereignisgesteuerte Funktion, die auf jede Art von Ereignis reagiert.

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Es handelt sich um einen String, der nicht von Google APIs verwendet wird. Sie können ihn jederzeit aktualisieren.
  • Die Projekt-ID muss für alle Google Cloud-Projekte eindeutig sein und ist unveränderlich (kann nach der Festlegung nicht mehr geändert werden). In der Cloud Console wird automatisch ein eindeutiger String generiert. Normalerweise ist es nicht wichtig, wie dieser String aussieht. In den meisten Codelabs müssen Sie auf die Projekt-ID verweisen (sie wird in der Regel als PROJECT_ID angegeben). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie es mit einem eigenen versuchen und sehen, ob es verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten
  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs zu verwenden. Die Durchführung dieses Codelabs sollte keine oder nur geringe Kosten verursachen. Wenn Sie Ressourcen herunterfahren möchten, damit Ihnen nach Abschluss dieser Anleitung keine Kosten mehr in Rechnung gestellt werden, können Sie die von Ihnen erstellten Ressourcen oder das gesamte Projekt löschen. Neue Nutzer von Google Cloud kommen für das Programm für kostenlose Testversionen mit einem Guthaben von 300$ infrage.

Cloud Shell starten

Während Sie Google Cloud von Ihrem Laptop aus per Fernzugriff nutzen können, wird in diesem Codelab Google Cloud Shell verwendet, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Klicken Sie in der Google Cloud Console rechts oben in der Symbolleiste auf das Cloud Shell-Symbol:

55efc1aaa7a4d3ad.png

Die Bereitstellung und Verbindung mit der Umgebung sollte nur wenige Augenblicke dauern. Anschließend sehen Sie in etwa Folgendes:

7ffe5cbb04455448.png

Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Alle Aufgaben in diesem Codelab können in einem Browser ausgeführt werden. Sie müssen nichts installieren.

3. Hinweis

Führen Sie in Cloud Shell den folgenden Befehl aus, um die erforderlichen Dienste zu aktivieren:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  eventarc.googleapis.com \
  run.googleapis.com

Legen Sie als Nächstes Ihre Region fest.

REGION=<YOUR_REGION>

In diesem Codelab erstellen Sie ein Dienstkonto mit den erforderlichen Eventarc-Berechtigungen und der Cloud Run-Aufruferrolle, um ein Ereignis aus Cloud Storage zu empfangen und die Cloud Run-Funktion aufzurufen.

Erstellen Sie zuerst das Dienstkonto.

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"

Weisen Sie als Nächstes dem Dienstkonto, das Ihrem Eventarc-Trigger zugeordnet ist, die Rolle „Eventarc-Ereignisempfänger“ (roles/eventarc.eventReceiver) für das Projekt zu, damit der Trigger Ereignisse vom Ereignisanbieter empfangen kann.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/eventarc.eventReceiver

Weisen Sie dem Dienstkonto dann die Rolle „Cloud Run-Aufrufer“ zu, damit es die Funktion aufrufen kann.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.invoker

4. Functions Framework für .NET

Das Functions Framework für .NET ist ein Open-Source-FaaS-Framework (Function as a Service) zum Schreiben portabler .NET-Funktionen, das vom Google Cloud Functions-Team entwickelt wurde.

Mit Functions Framework können Sie einfache Funktionen schreiben, die in vielen verschiedenen Umgebungen ausgeführt werden, darunter:

  • Google Cloud Run Functions
  • Ihre lokale Entwicklungsmaschine
  • Cloud Run und Cloud Run in GKE
  • Knative-basierte Umgebungen

In diesem Codelab verwenden Sie das Functions Framework für .NET und seine Vorlagen, um Cloud Functions in C# zu erstellen und bereitzustellen.

Führen Sie in Cloud Shell den folgenden Befehl aus, um Cloud Functions-Vorlagen für dotnet zu installieren:

dotnet new install Google.Cloud.Functions.Templates

Dadurch werden drei Vorlagen für dotnet installiert. Jede Vorlage ist in C#, F# und VB verfügbar. In diesem Lab verwenden Sie jedoch nur C#. Mit dem folgenden Befehl können Sie prüfen, ob Vorlagen installiert sind:

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-Funktion

Sie erstellen und stellen eine HTTP-Funktion bereit, die auf HTTP-Anfragen reagiert.

Erstellen Sie eine HTTP-Funktion mit der Vorlage gcf-http:

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

Dadurch wird ein Projekt und eine Function.cs-Datei erstellt, die auf HTTP-Anfragen reagiert.

Ändern Sie das Zielframework in der Datei .csproj in net8.0:

<TargetFramework>net8.0</TargetFramework>

Führen Sie den folgenden Befehl aus, um eine Cloud Run-Funktion direkt in Cloud Run bereitzustellen:

gcloud beta run deploy hello-http-function \
    --source . \
    --function HelloHttp.Function \
    --base-image dotnet8 \
    --region $REGION \
    --allow-unauthenticated

Wenn Sie die Bereitstellung als Cloud Functions (2. Generation) bevorzugen, verwenden Sie den folgenden Befehl:

gcloud functions deploy hello-http-function \
    --allow-unauthenticated \
    --entry-point HelloHttp.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-http

Nachdem Ihre Funktion bereitgestellt wurde, können Sie sie mit dem folgenden curl-Befehl aufrufen:

SERVICE_URL=$(gcloud run services describe hello-http-function --platform managed --region $REGION --format 'value(status.url)')

curl $SERVICE_URL

6. CloudEvent-Funktion – GCS

Sie erstellen und stellen eine CloudEvent-Funktion bereit, die auf Google Cloud Storage-Ereignisse (GCS) reagiert.

Erstellen Sie zuerst einen Cloud Storage-Bucket. Dies ist der Bucket, aus dem Sie später Ereignisse abrufen:

BUCKET_NAME="cloud-functions-bucket-${PROJECT_ID}"
gsutil mb -l us-central1 gs://${BUCKET_NAME}

CloudEvent-Funktion mit der Vorlage gcf-event erstellen:

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

Dadurch wird ein Projekt und eine Function.cs-Datei erstellt, die auf CloudEvent-Anfragen reagiert. Außerdem werden die Daten von CloudEvent in StorageObjectData geparst.

Ändern Sie das Zielframework in der Datei .csproj in net8.0:

<TargetFramework>net8.0</TargetFramework>

Wenn Sie eine Cloud Run-Funktion direkt in Cloud Run bereitstellen möchten, stellen Sie zuerst die Funktion bereit und erstellen dann einen Trigger dafür.

gcloud beta run deploy hello-gcs-function \
      --source . \
      --function HelloGcs.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Erstellen Sie nun den Trigger für die Cloud Run-Funktion.

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

Wenn Sie die Bereitstellung als Cloud Functions 2. Generation bevorzugen, können Sie die Funktion mit dem folgenden Befehl bereitstellen, indem Sie die Flags trigger-event und trigger-resource verwenden:

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

Nach einigen Minuten sollte die Funktion in der Cloud Console sichtbar sein:

c28654d74bb31420.png

Lösen Sie die Funktion aus, indem Sie eine Datei in den Speicher-Bucket hochladen:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Prüfen Sie anhand der Logs, ob die Funktion ausgelöst wurde:

Für eine Cloud Run-Funktion können Sie diesen Befehl ausführen:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

Für eine Funktion der 2. Generation können Sie diesen Befehl ausführen:

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

7. CloudEvent-Funktion – Pub/Sub

Sie erstellen und stellen eine CloudEvent-Funktion bereit, die auf Cloud Pub/Sub-Ereignisse reagiert.

Erstellen Sie zuerst ein Cloud Pub/Sub-Thema, das Ereignisse ausgibt:

TOPIC_NAME=cloud-functions-topic
gcloud pubsub topics create ${TOPIC_NAME}

CloudEvent-Funktion mit der Vorlage gcf-event erstellen:

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

Dadurch wird ein Projekt und eine Function.cs-Datei erstellt, die auf CloudEvent-Anfragen reagiert. Außerdem werden die Daten von CloudEvent standardmäßig in StorageObjectData geparst.

Ändern Sie das Zielframework in der Datei .csproj in net8.0:

<TargetFramework>net8.0</TargetFramework>

Ändern Sie StorageObjectData in MessagePublishedData, um Pub/Sub-Nachrichten zu parsen. Ändern Sie Google.Events.Protobuf.Cloud.Storage.V1 zu Google.Events.Protobuf.Cloud.PubSub.V1.

Am Ende sollte Ihre Funktion so aussehen:

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;
    }
}

Wenn Sie eine Cloud Run-Funktion direkt in Cloud Run bereitstellen möchten, stellen Sie zuerst die Funktion bereit und erstellen dann einen Trigger dafür.

gcloud beta run deploy hello-pubsub-function \
      --source . \
      --function HelloPubSub.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated \
      --service-account=$SERVICE_ACCOUNT_ADDRESS

Trigger für die Cloud Run-Funktion erstellen

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

Wenn Sie die Bereitstellung als Cloud Functions (2. Generation) bevorzugen, können Sie die Funktion mit dem Flag trigger-topic mit dem folgenden Befehl bereitstellen:

gcloud functions deploy hello-pubsub-function \
    --allow-unauthenticated \
    --entry-point HelloPubSub.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-topic ${TOPIC_NAME}

Nach einigen Minuten sollte die Funktion in der Cloud Console sichtbar sein:

3443808da7caf3bc.png

Funktionen durch Veröffentlichen einer Nachricht im Thema auslösen:

gcloud pubsub topics publish ${TOPIC_NAME} --message="World"

Prüfen Sie anhand der Logs, ob die Funktion ausgelöst wurde.

Für eine Cloud Run-Funktion können Sie diesen Befehl ausführen:

gcloud logging read "resource.labels.service_name=hello-pubsub-function AND textPayload: World" --format=json

Für eine Funktion der 2. Generation können Sie diesen Befehl ausführen:

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

8. CloudEvent-Funktion – ohne Typ

Wenn Sie mit CloudEvents experimentieren und noch kein Nutzlastdatenmodell haben, das Sie verwenden möchten, oder wenn Ihre Funktion in der Lage sein soll, jedes CloudEvent zu verarbeiten, können Sie eine untypisierte CloudEvent-Funktion verwenden.

CloudEvent-Funktion mit der Vorlage gcf-untyped-event erstellen:

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

Dadurch wird ein Projekt und eine Function.cs-Datei erstellt, die auf CloudEvent-Anfragen reagiert, ohne die Daten des CloudEvent zu parsen.

Ändern Sie das Zielframework in der Datei .csproj in net8.0:

<TargetFramework>net8.0</TargetFramework>

Wenn Sie eine Cloud Run-Funktion direkt in Cloud Run bereitstellen möchten, stellen Sie zuerst die Funktion bereit und erstellen dann einen Trigger dafür.

gcloud beta run deploy hello-untyped-function \
      --source . \
      --function HelloUntyped.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Erstellen Sie nun den Trigger für die Cloud Run-Funktion.

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

Wenn Sie die Bereitstellung als Cloud Functions 2. Generation bevorzugen, können Sie die Funktion mit dem folgenden Befehl bereitstellen, indem Sie die Flags trigger-event und trigger-resource verwenden:

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}

Die Funktion wird ausgelöst, wenn eine Datei in einen Speicher-Bucket hochgeladen wird.

Nach einigen Minuten sollte die Funktion in der Cloud Console sichtbar sein:

afe56530826787c6.png

Lösen Sie die Funktion aus, indem Sie eine Datei in den Speicher-Bucket hochladen:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Prüfen Sie anhand der Logs, ob die Funktion ausgelöst wurde.

Für eine Cloud Run-Funktion können Sie diesen Befehl ausführen:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

Für eine Funktion der 2. Generation können Sie diesen Befehl ausführen:

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

9. Glückwunsch!

Herzlichen Glückwunsch zum Abschluss des Codelabs.

Behandelte Themen

  • Functions Framework für .NET.
  • HTTP-Cloud-Funktion schreiben
  • CloudEvent-Funktion schreiben, die auf Cloud Storage-Ereignisse reagiert
  • Hier erfahren Sie, wie Sie eine CloudEvent-Funktion schreiben, die auf Cloud Pub/Sub-Ereignisse reagiert.
  • So schreiben Sie eine CloudEvent-Funktion, die auf beliebige Ereignistypen reagiert.