Ereignisverarbeitung aus Cloud Storage mit Eventarc- und Cloud Run-Funktionen auslösen

1. Übersicht

In diesem Lab erfahren Sie, wie Sie mit Cloud Storage-Bucket-Ereignissen und Eventarc die Ereignisverarbeitung auslösen. Sie verwenden Cloud Run-Funktionen, um Daten zu analysieren und Bilder zu verarbeiten. Die Funktion verwendet die Vision API von Google und speichert das resultierende Bild wieder im Cloud Storage-Bucket.

424779013ac38648.png

Lerninhalte

So erstellen Sie eine Pipeline für die Bildverarbeitung.

  • Speicher-Buckets konfigurieren
  • Cloud Run-Funktionen zum Lesen und Schreiben von Objekten in Cloud Storage erstellen
  • Eventarc-Trigger bereitstellen
  • Vision API zur Erkennung von Lebensmittelbildern einbinden
  • End-to-End-Lösung testen und validieren

Vorbereitung

  • Für dieses Lab wird davon ausgegangen, dass Sie mit der Cloud Console und mit Shell-Umgebungen vertraut sind.
  • Vorkenntnisse mit Cloud Storage, Cloud Run-Funktionen oder der Vision API sind hilfreich, aber nicht erforderlich.

2. Einrichtung und Anforderungen

Cloud-Projekt einrichten

  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.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.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 ist für alle Google Cloud-Projekte eindeutig und kann nach der Festlegung nicht mehr geändert werden. In der Cloud Console wird automatisch ein eindeutiger String generiert. In der Regel spielt es keine Rolle, wie er lautet. In den meisten Codelabs müssen Sie auf Ihre 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 Konto ausprobieren und prüfen, 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 die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs verwenden zu können. Die Durchführung dieses Codelabs ist kostenlos oder kostet nur sehr wenig. Wenn Sie die Ressourcen herunterfahren möchten, um Kosten nach Abschluss dieser Anleitung zu vermeiden, können Sie die von Ihnen erstellten Ressourcen oder das Projekt löschen. Neuen Google Cloud-Nutzern steht das kostenlose Testprogramm mit einem Guthaben von 300$ zur Verfügung.

Cloud Shell aktivieren

Klicken Sie zum Aktivieren von Cloud Shell auf das Symbol rechts neben der Suchleiste.

b02c63d9c7632ef8.png

Umgebung einrichten

  1. Erstellen Sie projekt- und ressourcenbezogene Umgebungsvariablen, indem Sie die folgenden Befehle im Cloud Shell-Terminal ausführen.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NAME=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export REGION=us-east1 
export UPLOAD_BUCKET_NAME=menu-item-uploads-$PROJECT_ID
export UPLOAD_BUCKET=gs://menu-item-uploads-$PROJECT_ID
export BUCKET_THUMBNAILS=gs://menu-item-thumbnails-$PROJECT_ID
export MENU_SERVICE_NAME=menu-service
export USER_EMAIL=$(gcloud config list account --format "value(core.account)")
  1. Aktivieren Sie die für das Lab erforderlichen APIs.
gcloud services enable \
    vision.googleapis.com \
    cloudfunctions.googleapis.com \
    pubsub.googleapis.com \
    cloudbuild.googleapis.com \
    logging.googleapis.com \
    eventarc.googleapis.com \
    artifactregistry.googleapis.com \
    run.googleapis.com \
    --quiet
  1. Repository klonen
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/cloud-functions

3. Cloud Storage-Buckets konfigurieren

Storage-Buckets erstellen

Erstellen Sie Cloud Storage-Buckets für Uploads und Miniaturansichten für Ihre Bildverarbeitungspipeline.

Verwenden Sie den Befehl gsutil mb und einen eindeutigen Namen, um zwei Buckets zu erstellen:

  1. Bucket für den ersten Upload von Bildern
  2. Bucket für Miniaturansichten zum Speichern generierter Miniaturansichten

Erstellen Sie einen Bucket, um neue Bilder hochzuladen:

gsutil mb -p $PROJECT_ID -l $REGION $UPLOAD_BUCKET

Beispielausgabe:

Creating gs://menu-item-uploads-cymbal-eats-8399-3119/...

Erstelle einen Bucket, um die generierten Miniaturansichten zu speichern:

gsutil mb -p $PROJECT_ID -l $REGION $BUCKET_THUMBNAILS

Beispielausgabe:

Creating gs://menu-item-thumbnails-cymbal-eats-8399-3119/...

Bucket-Berechtigungen aktualisieren

Aktualisieren Sie die Berechtigungen des Speicher-Buckets, um Nutzern Leseberechtigungen zu gewähren.

Verwenden Sie den Befehl „gsutil iam ch“, um Lese- und Schreibzugriff auf Objekte in Ihrem Bucket zu gewähren:

gsutil iam ch allUsers:objectViewer $UPLOAD_BUCKET
gsutil iam ch allUsers:objectViewer $BUCKET_THUMBNAILS

Beispielausgabe

Updated IAM policy for project [cymbal-eats-8399-3119].
[...]

4. Dienstkonten konfigurieren

Erstelle ein benutzerdefiniertes Dienstkonto für die Cloud Function, um Miniaturansichten zu verarbeiten:

export CF_SERVICE_ACCOUNT=thumbnail-service-sa
gcloud iam service-accounts create ${CF_SERVICE_ACCOUNT}

Gewähren Sie die Rolle artifactregistry.reader, um Lesevorgänge aus der Artifact Registry zuzulassen:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/artifactregistry.reader"

Weisen Sie die Rolle storage.objectCreator zu, um das Speichern generierter Bilder im Miniaturansichten-Bucket zu ermöglichen:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/storage.objectCreator"

Weisen Sie die Rolle run.invoker zu, um den Aufruf von Cloud Run-Diensten zuzulassen:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/run.invoker"

Weisen Sie die Rolle eventarc.eventReceiver zu, um Ereignisse von Anbietern zu empfangen:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/eventarc.eventReceiver"

Weisen Sie dem Cloud Storage-Dienstkonto die Rolle pubsub.publisher zu. So kann das Dienstkonto Ereignisse veröffentlichen, wenn Bilder in den Bucket hochgeladen werden.

GCS_SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER)

gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
    --member "serviceAccount:$GCS_SERVICE_ACCOUNT" \
    --role "roles/pubsub.publisher"

5. Bildverarbeitung – Funktion – Übersicht

Erstellen Sie eine Funktion, um ein Bild aus Cloud Storage herunterzuladen, die Größe des Bildes zu ändern und das Bild wieder in Cloud Storage hochzuladen. Die Funktion ruft die Vision API auf, um dem Bild ein Beschreibungslabel zuzuweisen. Die Funktion prüft das Beschreibungslabel. Wenn das Label das Bild als „Essen“ identifiziert, wird ein Ereignis an den Menüdienst gesendet, um das Bild und das Thumbnail des Menüpunkts zu aktualisieren.

4c3c3b758dba6a9f.png

Funktion auslösen

Cloud Storage-Funktionen basieren auf Pub/Sub-Benachrichtigungen von Cloud Storage und unterstützen ähnliche Ereignistypen:

In diesem Lab stellen Sie eine Funktion bereit und lösen sie aus, wenn ein Objekt in Cloud Storage abgeschlossen wird.

Objekt finalisieren

Object-Finalize-Ereignisse werden ausgelöst, wenn der Schreibvorgang eines Cloud Storage-Objekts erfolgreich abgeschlossen wurde. Dieses Ereignis wird also ausgelöst, wenn ein neues Objekt erstellt oder ein vorhandenes Objekt überschrieben wird. Archivierungs- und Metadatenaktualisierungsvorgänge werden von diesem Trigger ignoriert.

6. Cloud Storage einbinden

Cloud Storage ist ein Dienst zum Speichern Ihrer Objekte in Google Cloud. Ein Objekt ist ein unveränderliches Datenelement, das aus einer Datei mit einem beliebigen Format besteht. Objekte werden in Containern gespeichert, die als Buckets bezeichnet werden. Alle Buckets sind einem Projekt zugeordnet und Sie können Ihre Projekte in einer Organisation gruppieren. Clientbibliotheken und APIs erleichtern die Einbindung in Cloud Storage.

In diesem Lab verwenden Sie die Clientbibliothek, um Objekte in Cloud Storage zu lesen und zu schreiben.

Clientbibliothek installieren

Cloud-Clientbibliotheken sind in vielen gängigen Programmiersprachen verfügbar. Wenn Sie die Bibliotheken verwenden möchten, müssen Sie die Clientbibliothek installieren.

Clientbibliothek verwenden

Die Implementierungsdetails hängen weitgehend von der Programmiersprache ab. Wenn Sie die Clientbibliothek in Ihrer Anwendung verwenden möchten, müssen Sie zuerst die Cloud Storage-Abhängigkeiten importieren. Im Node.js-Projekt werden Importe beispielsweise in der Datei „package.json“ hinzugefügt. Im folgenden Snippet ist die entsprechende Meldung aus der package.json-Datei dieses Labs zu sehen.

package.json

{
    "name": "thumbnail-service",
    "version": "0.1.0",
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0",
      "@google-cloud/storage": "^5.18.2",
      "@google-cloud/vision": "^2.4.2",
        ...
    }
  }

CloudEvent-Callback registrieren

Registrieren Sie einen CloudEvent-Callback im Functions Framework, der von Cloud Storage ausgelöst wird, wenn ein neues Bild in den Bucket hochgeladen wird.

index.js

functions.cloudEvent('process-thumbnails', async (cloudEvent) => {
    console.log(`Event ID: ${cloudEvent.id}`);
    console.log(`Event Type: ${cloudEvent.type}`);
    ...

Speicherreferenzobjekt erstellen

Nachdem die Clientbibliotheken importiert wurden, müssen Sie einen neuen Speicherclient und Bucket erstellen, mit denen Ihre Anwendung interagieren wird.

index.js

const storage = new Storage();
const bucket = storage.bucket(file.bucket);
const thumbBucket = storage.bucket(process.env.BUCKET_THUMBNAILS);

Cloud Storage-Objekte herunterladen

index.js

await bucket.file(file.name).download({
            destination: originalFile
        });

Objekte in Cloud Storage hochladen

Sie haben drei Möglichkeiten, Uploadanfragen an Cloud Storage zu senden: einzelne Anfrage, fortsetzbarer Upload oder mehrteiliger Upload über die XML API. Verwenden Sie für größere Uploads oder Streaming-Uploads fortsetzbare Uploads. Bei der XML API werden Dateien in Teilen hochgeladen und zu einem einzelnen Objekt zusammengesetzt. Verwenden Sie für kleinere Objekte Uploads mit einer einzelnen Anfrage.

Im folgenden Code wird ein Bild mit einer einzelnen Anfrage in Cloud Storage hochgeladen.

index.js

const thumbnailImage = await thumbBucket.upload(thumbFile);

7. Vision API einbinden

Mit Cloud Vision können Entwickler auf einfache Weise Features zur visuellen Erkennung in Anwendungen einbinden. Hierzu zählen die Erkennung von Bildlabels, Gesichtern und Sehenswürdigkeiten, die optische Zeichenerkennung (Optical Character Recognition, OCR) sowie die Kennzeichnung anstößiger Inhalte mit Tags.

Clientbibliothek installieren

Cloud-Clientbibliotheken sind in vielen gängigen Programmiersprachen verfügbar. Wenn Sie die Bibliotheken verwenden möchten, müssen Sie die Clientbibliothek installieren.

Image Annotator-Client erstellen

Wenn Sie mithilfe der offiziellen Client-SDKs auf Google APIs zugreifen möchten, erstellen Sie ein Dienstobjekt, das auf dem Discovery-Dokument der API basiert. Dieses Dokument enthält eine API-Beschreibung für das SDK. Sie müssen es unter Angabe Ihrer Anmeldedaten vom Discovery-Dienst der Vision API abrufen.

index.js

const client = new vision.ImageAnnotatorClient();

Vision API-Anfrage erstellen

Die Vision API kann eine Elementerkennung für eine Bilddatei machen, indem sie den Inhalt der Bilddatei als Base64-codierten String an den Textkörper Ihrer Anfrage sendet.

So erstellen Sie eine Anfrage mit der Ressource „images“, um Ihr Bild zu annotieren. Die Anfrage an diese API erfolgt in Form eines Objekts mit einer Liste von Anfragen. Jedes Element der Liste enthält zwei Informationen:

  • Die Bilddaten mit Base64-Codierung
  • Eine Liste der Elemente, die Sie zu diesem Bild annotieren möchten

index.js

        const client = new vision.ImageAnnotatorClient();
        const visionRequest = {
            image: { source: { imageUri: `gs://${file.bucket}/${file.name}` } },
            features: [
                { type: 'LABEL_DETECTION' },
            ]
        };
        const visionPromise = client.annotateImage(visionRequest);

8. Cloud Run-Funktionen bereitstellen

Dieser Dienst zum Ändern der Bildgröße ist Teil des größeren Cymbal Eats-Systems. In diesem Abschnitt stellen Sie nur die Komponenten bereit, die sich auf die Bildverarbeitungsfunktion beziehen. Die vollständige Installation umfasst eine Benutzeroberfläche zum Hochladen des Bilds und eine Downstream-Anfrage zum Speichern der resultierenden Metadaten. Diese Funktionen werden im Rahmen dieses Labs nicht installiert.

Die folgenden Komponenten werden während der Bereitstellung der Funktion erstellt:

  • Cloud Run-Funktionen
  • Eventarc-Trigger
  • Pub/Sub-Thema und -Abo

Führen Sie im Cloud Shell-Terminal den folgenden Befehl aus, um Cloud Run-Funktionen mit einem Trigger-Bucket auf der menu-item-uploads-$PROJECT_ID bereitzustellen:

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.

Cloud Run-Funktionen bereitstellen:

gcloud beta run deploy process-thumbnails \
      --source=thumbnail \
      --function process-thumbnails \
      --region $REGION \
      --base-image google-22-full/nodejs20 \
      --no-allow-unauthenticated \
      --project=$PROJECT_ID \
--service-account="${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--set-env-vars=BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS,MENU_SERVICE_URL=$MENU_SERVICE_URL \
  --max-instances=1 \
  --quiet

Beispielausgabe:

Done.                                                                                                                                                                                    
Service [process-thumbnails] revision [process-thumbnails-00001-abc] has been deployed and is serving 100 percent of traffic.
Service URL: https://process-thumbnails-000000000.us-east1.run.app

Erstellen Sie den Trigger:

gcloud eventarc triggers create process-thumbnails-trigger \
     --location=$REGION \
     --destination-run-service=process-thumbnails \
    --destination-run-region=$REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$UPLOAD_BUCKET_NAME" \
     --service-account="${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com"

Beispielausgabe:

Creating trigger [process-thumbnails-trigger] in project [qwiklabs-gcp-02-53f8532696e1], location [us-east1]...done.                                                                     
WARNING: It may take up to 2 minutes for the new trigger to become active.

Wenn die Triggerbereitstellung aufgrund eines Berechtigungsproblems fehlschlägt, warten Sie, bis die IAM-Änderungen aus dem vorherigen Schritt übernommen wurden. Das dauert in der Regel 1–2 Minuten. Versuchen Sie dann noch einmal, die Bereitstellung auszuführen.

Beispiel für eine Fehlerausgabe:

...If you recently started to use Eventarc, it may take a few minutes before all necessary permissions are propagated to the Service Agent...
[...] 

Prüfen Sie in der Cloud Console den Cloud Run-Dienst, der für die Funktion erstellt wurde:

546c5c951cf0f2f.png

Prüfen Sie in der Cloud Console den Eventarc, der für die Funktion erstellt wurde:

dec11309016b09ac.png

Prüfen Sie in der Cloud Console das Pub/Sub-Thema und das Abo, die für den Eventarc-Trigger erstellt wurden:

affe089c39ae1465.png

a4c41ede2af300db.png

9. End-to-End-Lösung testen und validieren

Laden Sie ein neues Foto in Cloud Storage hoch und verfolgen Sie den Fortschritt der Pipeline, während die Bilder analysiert werden. Sie testen die End-to-End-Lösung, indem Sie Cloud Functions-Protokolle überwachen.

Bild hochladen

ab7b43f876f9c3a9.jpeg

  1. Speichern Sie dieses Bild auf Ihrem lokalen Computer.
  2. Benennen Sie die Datei in 1.jpg um.
  3. Öffnen Sie die Cloud Storage-Konsole.
  4. Klicken Sie auf den Bucket menu-item-uploads-....
  5. Klicken Sie auf DATEIEN HOCHLADEN.
  6. Laden Sie 1.jpg in den Storage-Bucket hoch.
  7. Rufen Sie in der Cloud Console Cloud Run auf.
  8. Klicke auf process-thumbails.
  9. Klicken Sie auf den Tab LOGS.

fca8e4bafbdf135d.png

  1. Rufe den Bucket menu-item-thumbnails-$PROJECT_ID Cloud Storage auf.
  2. Prüfen, ob das Miniaturbild im Miniatur-Bucket erstellt wurde

1b6dee72a1fde681.png

Bild hochladen, das keine Lebensmittel zeigt

Um zu prüfen, ob die Funktion richtig funktioniert, laden Sie ein Bild hoch, das kein Objekt enthält, das als „Essen“ klassifiziert werden würde.

c76dd525765f66a6.jpeg

  1. Speichern Sie dieses Bild auf Ihrem lokalen Computer.
  2. Benennen Sie die Datei in 2.jpg um.
  3. Öffnen Sie die Cloud Storage-Konsole.
  4. Klicken Sie auf den Bucket menu-item-uploads-....
  5. Klicken Sie auf DATEIEN HOCHLADEN.
  6. Laden Sie 2.jpg in den Storage-Bucket hoch.
  7. Rufen Sie in der Cloud Console Cloud Run auf.
  8. Klicke auf process-thumbails.
  9. Klicken Sie auf den Tab LOGS.

18b1e30ee78d3955.png

10. Glückwunsch!

Sie haben das Lab erfolgreich abgeschlossen.

Nächste Schritte:

Weitere Cymbal Eats-Codelabs:

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, können Sie entweder das Projekt löschen, das die Ressourcen enthält, oder das Projekt beibehalten und die einzelnen Ressourcen löschen.

Projekt löschen

Am einfachsten vermeiden Sie weitere Kosten durch Löschen des für die Anleitung erstellten Projekts.