获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

Enqueue-Funktionen mit Cloud Tasks

Aufgabenwarteschlangenfunktionen nutzen Google Cloud Tasks , um Ihrer App zu helfen, zeitaufwändige, ressourcenintensive oder bandbreitenbegrenzte Aufgaben asynchron außerhalb Ihres Hauptanwendungsflusses auszuführen.

Stellen Sie sich beispielsweise vor, Sie möchten Sicherungen einer großen Menge von Bilddateien erstellen, die derzeit auf einer API mit einer Ratenbegrenzung gehostet werden. Um ein verantwortungsvoller Verbraucher dieser API zu sein, müssen Sie deren Ratenbegrenzungen respektieren. Außerdem kann diese Art von lang andauernden Jobs aufgrund von Zeitüberschreitungen und Speicherbeschränkungen fehleranfällig sein.

Um diese Komplexität zu verringern, können Sie eine Aufgabenwarteschlangenfunktion schreiben, die grundlegende Aufgabenoptionen wie „ scheduleTime “ und „ dispatchDeadline “ festlegt und die Funktion dann an eine Warteschlange in Cloud Tasks übergibt. Die Cloud Tasks-Umgebung wurde speziell entwickelt, um eine effektive Überlastungskontrolle und Wiederholungsrichtlinien für diese Art von Vorgängen sicherzustellen.

Das Firebase SDK for Cloud Functions for Firebase v3.20.1 und höher interagiert mit Firebase Admin SDK v10.2.0 und höher, um Aufgabenwarteschlangenfunktionen zu unterstützen.

Die Verwendung von Aufgabenwarteschlangenfunktionen mit Firebase kann zu Gebühren für die Verarbeitung von Cloud-Aufgaben führen. Weitere Informationen finden Sie unter Preise für Cloud-Aufgaben .

Aufgabenwarteschlangenfunktionen erstellen

Um Aufgabenwarteschlangenfunktionen zu verwenden, folgen Sie diesem Arbeitsablauf:

  1. Schreiben Sie mit dem Firebase SDK for Cloud Functions eine Aufgabenwarteschlangenfunktion.
  2. Testen Sie Ihre Funktionen mit der Firebase Local Emulator Suite.
  3. Stellen Sie Ihre Funktion mit der Firebase CLI bereit. Wenn Sie Ihre Aufgabenwarteschlangenfunktion zum ersten Mal bereitstellen, erstellt die CLI eine Aufgabenwarteschlange in Cloud Tasks mit Optionen (Ratenbegrenzung und Wiederholung), die in Ihrem Quellcode angegeben sind.
  4. Fügen Sie der neu erstellten Aufgabenwarteschlange Aufgaben hinzu und übergeben Sie bei Bedarf Parameter, um einen Ausführungszeitplan einzurichten. Sie können dies erreichen, indem Sie den Code mit dem Admin SDK schreiben und ihn in Cloud Functions for Firebase bereitstellen.

Aufgabenwarteschlangenfunktionen schreiben

Verwenden Sie onTaskDispatched , um mit dem Schreiben von Aufgabenwarteschlangenfunktionen zu beginnen. Ein wichtiger Teil beim Schreiben einer Aufgabenwarteschlangenfunktion besteht darin, die Wiederholungs- und Ratenbegrenzungskonfiguration pro Warteschlange festzulegen. Codebeispiele auf dieser Seite basieren auf einer App, die einen Dienst einrichtet, der alle Bilder aus dem Astronomy Picture of the Day der NASA sichert:

Konfiguration der Aufgabenwarteschlange

Aufgabenwarteschlangenfunktionen verfügen über einen leistungsstarken Satz von Konfigurationseinstellungen, um die Ratenbegrenzungen und das Wiederholungsverhalten einer Aufgabenwarteschlange präzise zu steuern:

exports.backupapod = onTaskDispatched(
    {
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }, async (req) => {
  • retryConfig.maxAttempts=5 : Jede Aufgabe in der Aufgabenwarteschlange wird automatisch bis zu 5 Mal wiederholt. Dies trägt dazu bei, vorübergehende Fehler wie Netzwerkfehler oder vorübergehende Dienstunterbrechungen eines abhängigen externen Dienstes zu mindern.
  • retryConfig.minBackoffSeconds=60 : Jede Aufgabe wird mindestens 60 Sekunden nach jedem Versuch wiederholt. Dies bietet einen großen Puffer zwischen den einzelnen Versuchen, sodass wir die 5 Wiederholungsversuche nicht zu schnell erschöpfen müssen.
  • rateLimits.maxConcurrentDispatch=6 : Höchstens 6 Aufgaben werden zu einem bestimmten Zeitpunkt abgefertigt. Dies trägt dazu bei, einen stetigen Strom von Anforderungen an die zugrunde liegende Funktion sicherzustellen und die Anzahl aktiver Instanzen und Kaltstarts zu reduzieren.

Testen der Aufgabenwarteschlangenfunktionen mit der Firebase Local Emulator Suite

Aufgabenwarteschlangenfunktionen in der Firebase Local Emulator Suite werden als einfache HTTP-Funktionen verfügbar gemacht. Sie können eine emulierte Aufgabenfunktion testen, indem Sie eine HTTP-POST-Anforderung mit einer json-Datennutzlast senden:

 # start the Local Emulator Suite
 firebase emulators:start

 # trigger the emulated task queue function
 curl \
  -X POST                                            # An HTTP POST request...
  -H "content-type: application/json" \              # ... with a JSON body
  http://localhost:$PORT/$PROJECT_ID/$REGION/$NAME \ # ... to function url
  -d '{"data": { ... some data .... }}'              # ... with JSON encoded data

Bereitstellen der Aufgabenwarteschlangenfunktion

Stellen Sie die Aufgabenwarteschlangenfunktion mithilfe der Firebase-CLI bereit:

$ firebase deploy --only functions:backupapod

Wenn Sie zum ersten Mal eine Aufgabenwarteschlangenfunktion bereitstellen, erstellt die CLI eine Aufgabenwarteschlange in Cloud Tasks mit Optionen (Ratenbegrenzung und Wiederholung), die in Ihrem Quellcode angegeben sind.

Wenn beim Bereitstellen von Funktionen Berechtigungsfehler auftreten, stellen Sie sicher, dass dem Benutzer, der die Bereitstellungsbefehle ausführt, die entsprechenden IAM-Rollen zugewiesen sind.

Stellen Sie die Funktion in die Warteschlange

Aufgabenwarteschlangenfunktionen können in Cloud Tasks aus einer vertrauenswürdigen Serverumgebung wie Cloud Functions for Firebase mit dem Firebase Admin SDK for Node.js in die Warteschlange gestellt werden. Wenn Sie neu bei den Admin-SDKs sind, lesen Sie Firebase zu einem Server hinzufügen, um loszulegen.

In einem typischen Ablauf erstellt das Admin SDK eine neue Aufgabe, stellt sie in Cloud Tasks in die Warteschlange und legt die Konfiguration für die Aufgabe fest:

exports.enqueuebackuptasks = onRequest(
    async (_request, response) => {
      const queue = getFunctions().taskQueue("backupapod");
      const targetUri = await getFunctionUrl("backupapod");

      const enqueues = [];
      for (let i = 0; i <= BACKUP_COUNT; i += 1) {
        const iteration = Math.floor(i / HOURLY_BATCH_SIZE);
        // Delay each batch by N * hour
        const scheduleDelaySeconds = iteration * (60 * 60);

        const backupDate = new Date(BACKUP_START_DATE);
        backupDate.setDate(BACKUP_START_DATE.getDate() + i);
        // Extract just the date portion (YYYY-MM-DD) as string.
        const date = backupDate.toISOString().substring(0, 10);
        enqueues.push(
            queue.enqueue({date}, {
              scheduleDelaySeconds,
              dispatchDeadlineSeconds: 60 * 5, // 5 minutes
              uri: targetUri,
            }),
        );
      }
      await Promise.all(enqueues);
      response.sendStatus(200);
    });
  • scheduleDelaySeconds : Der Beispielcode versucht, die Ausführung von Aufgaben zu verteilen, indem er der N-ten Aufgabe eine Verzögerung von N-ten Minuten zuordnet. Dies bedeutet, dass ~ 1 Aufgabe/Minute ausgelöst wird. Beachten Sie, dass Sie scheduleTime auch verwenden können, wenn Sie möchten, dass Cloud Tasks eine Aufgabe zu einem bestimmten Zeitpunkt auslöst.
  • dispatchDeadlineSeconds : Maximale Zeit, die Cloud Tasks auf den Abschluss einer Aufgabe wartet. Cloud Tasks wiederholt die Aufgabe nach der Wiederholungskonfiguration der Warteschlange oder bis diese Frist erreicht ist. Im Beispiel ist die Warteschlange so konfiguriert, dass die Aufgabe bis zu 5 Mal wiederholt wird, aber die Aufgabe wird automatisch abgebrochen, wenn der gesamte Vorgang (einschließlich der Wiederholungsversuche) länger als 5 Minuten dauert.

Rufen Sie den Ziel-URI ab und fügen Sie ihn ein

Da Cloud Functions for Firebase (2. Generation) keine deterministischen HTTP-URLs unterstützt, müssen Sie den Ziel-URI manuell abrufen und in jede eingereihte Aufgabe einfügen. Sie können die URL für Ihre Funktion auch programmgesteuert abrufen, wie unten gezeigt:

/**
 * Get the URL of a given v2 cloud function.
 *
 * @param {string} name the function's name
 * @param {string} location the function's location
 * @return {Promise<string>} The URL of the function
 */
async function getFunctionUrl(name, location="us-central1") {
  if (!auth) {
    auth = new GoogleAuth({
      scopes: "https://www.googleapis.com/auth/cloud-platform",
    });
  }
  const projectId = await auth.getProjectId();
  const url = "https://cloudfunctions.googleapis.com/v2beta/" +
    `projects/${projectId}/locations/${location}/functions/${name}`;

  const client = await auth.getClient();
  const res = await client.request({url});
  const uri = res.data?.serviceConfig?.uri;
  if (!uri) {
    throw new Error(`Unable to retreive uri for function at ${url}`);
  }
  return uri;
}

Fehlerbehebung

Aktivieren Sie die Protokollierung von Cloud-Aufgaben

Protokolle von Cloud Tasks enthalten nützliche Diagnoseinformationen wie den Status der mit einer Aufgabe verknüpften Anfrage. Standardmäßig sind Protokolle von Cloud Tasks aufgrund der großen Menge an Protokollen, die möglicherweise für Ihr Projekt generiert werden können, deaktiviert. Wir empfehlen Ihnen, die Debug-Protokolle zu aktivieren, während Sie Ihre Aufgabenwarteschlangenfunktionen aktiv entwickeln und debuggen. Siehe Aktivieren der Protokollierung .

IAM-Berechtigungen

Möglicherweise sehen PERMISSION DENIED Fehler, wenn Sie Aufgaben in die Warteschlange stellen oder wenn Cloud Tasks versucht, Ihre Aufgabenwarteschlangenfunktionen aufzurufen. Stellen Sie sicher, dass Ihr Projekt über die folgenden IAM-Bindungen verfügt:

  • Die zum Einreihen von Aufgaben in Cloud Tasks verwendete Identität benötigt die IAM-Berechtigung cloudtasks.tasks.create .

    Im Beispiel ist dies das Standarddienstkonto von App Engine

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • Die zum Einreihen von Aufgaben in Cloud Tasks verwendete Identität benötigt die Berechtigung, das mit einer Aufgabe in Cloud Tasks verknüpfte Dienstkonto zu verwenden.

    Im Beispiel ist dies das App Engine-Standarddienstkonto .

Anweisungen zum Hinzufügen des App Engine-Standarddienstkontos als Benutzer des App Engine-Standarddienstkontos finden Sie in der Google Cloud IAM-Dokumentation .

  • Die zum Auslösen der Aufgabenwarteschlangenfunktion verwendete Identität benötigt die cloudfunctions.functions.invoke Berechtigung.

    Im Beispiel ist dies das Standarddienstkonto von App Engine

gcloud functions add-iam-policy-binding $FUNCTION_NAME \
  --region=us-central1 \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudfunctions.invoker