Google Cloud Functions in C#

1. Einführung

Google Cloud Run-Funktionen sind eine ereignisgesteuerte serverlose Computing-Plattform. Mit Cloud Run-Funktionen können Sie Code schreiben, ohne sich um die Bereitstellung von Ressourcen oder die Skalierung für wechselnde 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. eine Nachricht, die in Cloud Pub/Sub veröffentlicht wird, oder eine Datei, die in Cloud Storage hochgeladen wird.

efb3268e3b74ed4f.png

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

Lerninhalte

  • Functions Framework für .NET
  • So schreiben Sie eine HTTP-Funktion.
  • So schreiben Sie eine durch Ereignis ausgelöste Funktion, die auf Cloud Storage-Ereignisse reagiert.
  • Eine ereignisgesteuerte Funktion schreiben, die auf Cloud Pub/Sub-Ereignisse reagiert
  • So schreiben Sie eine durch Ereignis ausgelöste Funktion, die auf einen beliebigen Ereignistyp reagiert.

2. Einrichtung und Anforderungen

Umgebung für das selbstbestimmte 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 ist ein Zeichenstring, der von Google APIs nicht verwendet wird. Sie können ihn jederzeit aktualisieren.
  • Die Projekt-ID muss für alle Google Cloud-Projekte eindeutig sein und ist unveränderlich. Sie kann nach dem Festlegen nicht mehr geändert werden. Die Cloud Console generiert automatisch einen eindeutigen String. ist Ihnen meist egal, was es ist. In den meisten Codelabs musst du auf die Projekt-ID verweisen, die üblicherweise als PROJECT_ID gekennzeichnet ist. Wenn Ihnen die generierte ID nicht gefällt, können Sie eine weitere zufällige ID erstellen. Alternativ können Sie Ihr eigenes Gerät ausprobieren, um zu 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 gibt es noch einen dritten Wert, die Projektnummer, die von manchen APIs verwendet wird. Weitere Informationen zu allen drei Werten finden Sie in der Dokumentation.
  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs verwenden zu können. Die Ausführung dieses Codelabs sollte nur wenige Kosten verursachen, wenn überhaupt. Wenn Sie die Ressourcen deaktivieren möchten, damit keine Kosten über diese Anleitung hinaus anfallen, können Sie die von Ihnen erstellten Ressourcen oder das gesamte Projekt löschen. Neuen Nutzern der Google Cloud Platform steht das kostenlose Testprogramm mit einem Guthaben von 300 $ zur Verfügung.

Cloud Shell starten

Sie können Google Cloud zwar per Fernzugriff von Ihrem Laptop aus nutzen, in diesem Codelab verwenden Sie jedoch Google Cloud Shell, 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 Minuten dauern. Wenn er abgeschlossen ist, sollten Sie in etwa Folgendes sehen:

7ffe5cbb04455448.png

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

3. Vorbereitung

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>

Für dieses Codelab erstellen Sie ein Dienstkonto mit den erforderlichen EventArc-Berechtigungen und der Cloud Run-Aufrufer-Rolle, um ein Ereignis von 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"

Als Nächstes weisen Sie dem Dienstkonto, das mit Ihrem Eventarc-Trigger verknüpft ist, die Rolle „Eventarc Event Receiver“ (roles/eventarc.eventReceiver) für das Projekt zu, damit der Trigger Ereignisse von Ereignisanbietern 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

Functions Framework for .NET ist ein Open-Source-FaaS-Framework (Function as a Service) zum Schreiben portierbarer .NET-Funktionen, das Ihnen vom Google Cloud Functions-Team zur Verfügung gestellt wird.

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

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

In diesem Codelab verwenden Sie Functions Framework for .NET und die zugehörigen Vorlagen, um Cloud Functions-Funktionen 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, aber in diesem Lab verwenden Sie nur C#. Sie können mit dem folgenden Befehl 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 werden ein Projekt und eine Function.cs-Datei als Antwort auf HTTP-Anfragen erstellt.

Ändern Sie in der Datei .csproj das Ziel-Framework 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 die 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 eine CloudEvent Functions-Funktion, die auf Google Cloud Storage-Ereignisse (GCS) reagiert, und stellen sie bereit.

Erstellen Sie zuerst einen Cloud Storage-Bucket. Aus diesem Bucket werden später Ereignisse abgerufen:

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

Erstellen Sie mit der Vorlage gcf-event eine CloudEvent-Funktion:

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

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

Ändern Sie das Ziel-Framework in der Datei .csproj in net8.0:

<TargetFramework>net8.0</TargetFramework>

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

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

Erstellen Sie jetzt 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 Funktion lieber als Cloud Functions-Funktion der 2. Generation bereitstellen möchten, können Sie sie mit den Flags trigger-event und trigger-resource mit dem folgenden Befehl bereitstellen:

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 angezeigt werden:

c28654d74bb31420.png

Die Funktion durch Hochladen einer Datei in den Speicher-Bucket auslösen:

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

Prüfen Sie anhand der Protokolle, 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 den folgenden 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 werden ein Projekt und eine Function.cs-Datei erstellt, die auf CloudEvent-Anfragen antworten. Außerdem werden die Daten von CloudEvent standardmäßig in StorageObjectData geparst.

Ändern Sie das Ziel-Framework 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 in Google.Events.Protobuf.Cloud.PubSub.V1.

Ihre Funktion sollte am Ende 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, müssen Sie zuerst die Funktion bereitstellen und dann einen Trigger dafür erstellen.

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

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

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 Funktion lieber als Cloud Functions der 2. Generation bereitstellen möchten, können Sie sie mit dem folgenden Befehl und dem Flag trigger-topic 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 angezeigt werden:

3443808da7caf3bc.png

Lösen Sie die Funktion aus, indem Sie eine Nachricht im Thema veröffentlichen:

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

Prüfen Sie anhand der Protokolle, 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 den folgenden Befehl ausführen:

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

8. CloudEvent-Funktion – untypisiert

Wenn Sie mit CloudEvents experimentieren und noch kein Nutzlastdatenmodell haben, das Sie verwenden möchten, oder Ihre Funktion alle Cloud-Ereignisse verarbeiten soll, 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 werden ein Projekt und eine Function.cs-Datei erstellt, die auf CloudEvent-Anfragen antworten, ohne dass versucht wird, die Daten der CloudEvent zu parsen.

Ändern Sie in der Datei .csproj das Ziel-Framework in net8.0:

<TargetFramework>net8.0</TargetFramework>

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

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

Erstellen Sie jetzt 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 Funktion lieber als Cloud Functions-Funktion der 2. Generation bereitstellen möchten, können Sie sie mit dem folgenden Befehl mithilfe der Flags trigger-event und trigger-resource bereitstellen:

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 angezeigt werden:

afe56530826787c6.png

Die Funktion durch Hochladen einer Datei in den Speicher-Bucket auslösen:

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

Prüfen Sie durch Lesen 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 den folgenden 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
  • Cloud Functions-HTTP-Funktion schreiben
  • CloudEvent-Funktion schreiben, die auf Cloud Storage-Ereignisse reagiert
  • CloudEvent-Funktion schreiben, die auf Cloud Pub/Sub-Ereignisse reagiert
  • CloudEvent-Funktionen schreiben, die auf beliebige Ereignistypen reagieren