Google Cloud Functions in C#

1. Einführung

Google Cloud Run-Funktionen ist eine ereignisgesteuerte serverlose Computing-Plattform. Mit Cloud Run-Funktionen können Sie Ihren Code schreiben, ohne sich um die Bereitstellung von Ressourcen oder die Skalierung kümmern zu müssen, um sich an sich ändernde Anforderungen anzupassen.

Es gibt zwei Arten von Cloud Run-Funktionen:

  • HTTP-Funktionen reagieren auf HTTP-Anfragen.
  • Ereignisfunktionen werden durch Ereignisse ausgelöst, z. B. durch die Veröffentlichung einer Nachricht in Cloud Pub/Sub oder den Upload einer Datei in Cloud Storage.

efb3268e3b74ed4f.png

In diesem Codelab erfahren Sie, wie Sie eigene Cloud Run-Funktionen in C# erstellen. Konkret werden Sie C#-Funktionen bereitstellen, die auf HTTP- und CloudEvents aus verschiedenen Google Cloud-Quellen reagieren.

Lerninhalte

  • Functions Framework für .NET
  • HTTP-Funktionen schreiben
  • Eine ereignisgesteuerte Funktion schreiben, die auf Cloud Storage-Ereignisse reagiert
  • Eine ereignisgesteuerte Funktion schreiben, die auf Cloud Pub/Sub-Ereignisse reagiert
  • So schreiben Sie eine ereignisgesteuerte Funktion, die auf jeden Ereignistyp reagiert.

2. Einrichtung und Anforderungen

Einrichtung der Umgebung im eigenen Tempo

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie ein Konto 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 kann nach der Festlegung nicht mehr geändert werden. In der Cloud Console wird automatisch ein eindeutiger String generiert. Normalerweise spielt es keine Rolle, wie er lautet. In den meisten Codelabs müssen Sie auf die Projekt-ID verweisen (normalerweise als PROJECT_ID gekennzeichnet). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige generieren. Alternativ können Sie Ihr eigenes Gerät testen, 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: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten finden Sie in der Dokumentation.
  1. Als Nächstes müssen Sie in der Cloud Console die Abrechnung 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 der Vorgang abgeschlossen ist, sollte in etwa Folgendes angezeigt werden:

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 auf Google Cloud. Dadurch werden 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 Rolle „Cloud Run-Aufrufer“, 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 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

Functions Framework for .NET ist ein Open-Source-FaaS-Framework (Function as a Service) zum Schreiben portabler .NET-Funktionen. Es wurde vom Google Cloud Functions-Team entwickelt.

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 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#. 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 erstellt, die auf HTTP-Anfragen reagieren.

Ä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 – Google Cloud Storage

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

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}

CloudEvent-Funktion mit der Vorlage gcf-event erstellen:

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 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-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 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, über das Ereignisse gesendet werden:

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 in der Datei .csproj das Ziel-Framework 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-Funktion 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 diesen 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 reagieren, ohne dass die Daten der CloudEvent geparst werden.

Ä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 den Flags trigger-event und trigger-resource mit dem folgenden Befehl 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 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 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-Funktionen schreiben
  • CloudEvent-Funktion schreiben, die auf Cloud Storage-Ereignisse reagiert
  • CloudEvent-Funktion schreiben, die auf Cloud Pub/Sub-Ereignisse reagiert
  • Eine CloudEvent-Funktion schreiben, die auf jeden Ereignistyp reagiert