Dodawanie funkcji do kolejki za pomocą Cloud Tasks


Funkcje kolejki zadań korzystają z Cloud Tasks Google, dzięki czemu aplikacja może asynchronicznie wykonywać zadania czasochłonne, wymagające znacznych zasobów lub o ograniczonej przepustowości poza głównym przepływem aplikacji.

Załóżmy na przykład, że chcesz utworzyć kopie zapasowe dużego zestawu plików graficznych hostowanych obecnie przez interfejs API z ograniczeniem liczby żądań. Aby być odpowiedzialnym konsumentem tego interfejsu API, musisz respektować jego limity liczby żądań. Poza tym tego rodzaju długotrwałe zadanie może być podatne na awarię z powodu przekroczenia limitów czasu i limitu pamięci.

Aby zmniejszyć to złożoność, możesz napisać funkcję kolejki zadań, która ustawia podstawowe opcje zadań, takie jak scheduleTime i dispatchDeadline, a następnie przekazuje tę funkcję do kolejki w Cloud Tasks. Środowisko Cloud Tasks zostało zaprojektowane tak, aby zapewnić skuteczną kontrolę nadmiaru i ponawiać próby stosowania zasad w przypadku tego typu operacji.

Pakiet Firebase SDK dla Cloud Functions dla Firebase w wersji 3.20.1 lub nowszej współdziała z pakietem Firebase Admin SDK w wersji 10.2.0 lub nowszej, aby obsługiwać funkcje kolejki zadań.

Korzystanie z funkcji kolejki zadań w Firebase może wiązać się z opłatami za przetwarzanie w Cloud Tasks. Więcej informacji znajdziesz w cenniku Cloud Tasks.

Tworzenie funkcji kolejki zadań

Aby korzystać z funkcji kolejki zadań, postępuj zgodnie z instrukcjami poniżej:

  1. utworzyć funkcję kolejki zadań za pomocą pakietu SDK Firebase dla Cloud Functions.
  2. Przetestuj funkcję, aktywując ją za pomocą żądania HTTP.
  3. Wdróż funkcję za pomocą interfejsu wiersza poleceń Firebase. Przy pierwszym wdrażaniu funkcji kolejki zadań interfejs wiersza poleceń utworzy w Cloud Tasks kolejkę zadań z opcjami (ograniczeniem liczby żądań i ponawianiem prób) określonymi w kodzie źródłowym.
  4. Dodaj zadania do nowo utworzonej kolejki zadań i przekaż odpowiednie parametry, aby w razie potrzeby skonfigurować harmonogram wykonywania. Możesz to osiągnąć, pisząc kod za pomocą pakietu Admin SDK i wdrażając go w Cloud Functions dla Firebase.

Zapis funkcji kolejki zadań

Aby zacząć pisać funkcje kolejki zadań, użyj narzędzia onDispatch. Ważnym elementem pisania funkcji kolejki zadań jest ustawienie liczby ponownych prób w kolejce i konfiguracji ograniczenia liczby żądań. Przykładowe fragmenty kodu na tej stronie pochodzą z aplikacji konfigurowania usługi tworzącej kopie zapasowe wszystkich obrazów z astronomicznego zdjęcia dnia NASA:

Skonfiguruj funkcje kolejki zadań

Funkcje kolejki zadań mają rozbudowany zestaw ustawień konfiguracji, które pozwalają dokładnie kontrolować ograniczenia liczby żądań i zachowanie ponawiania ich w tej kolejce:

exports.backupApod = functions
    .runWith( {secrets: ["NASA_API_KEY"]})
    .tasks.taskQueue({
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }).onDispatch(async (data) => {
  • retryConfig.maxAttempts=5: każde zadanie w kolejce jest automatycznie ponawiane maksymalnie 5 razy. Pomaga to eliminować błędy przejściowe, takie jak błędy sieci lub tymczasowe przerwy w działaniu zależnych usługi zewnętrznej.
  • retryConfig.minBackoffSeconds=60: każde zadanie jest ponawiane w odstępie co najmniej 60 sekund od każdej z nich. Zwiększa to bufor między kolejnymi próbami, dzięki czemu nie musimy się spieszyć, aby za szybko wyczerpać 5 prób.
  • rateLimits.maxConcurrentDispatch=6: w danym momencie wysyłanych jest maksymalnie 6 zadań. Pomaga to zapewnić stabilny strumień żądań do funkcji bazowej oraz zmniejsza liczbę aktywnych instancji i uruchomień „na zimno”.

Testowanie funkcji kolejki zadań

Funkcje kolejki zadań w Pakiecie emulatorów lokalnych Firebase są wyeksponowane jako proste funkcje HTTP. Możesz przetestować emulowaną funkcję zadania, wysyłając żądanie HTTP POST z ładunkiem danych JSON:

 # start the Firebase Emulators
 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

Wdrażanie funkcji kolejki zadań

Wdróż funkcję kolejki zadań za pomocą interfejsu wiersza poleceń Firebase:

$ firebase deploy --only functions:backupApod

Podczas wdrażania funkcji kolejki zadań po raz pierwszy interfejs wiersza poleceń tworzy w Cloud Tasks kolejkę zadań z opcjami (ograniczenie liczby żądań i ponawianie prób) określonymi w kodzie źródłowym.

Jeśli podczas wdrażania funkcji wystąpią błędy uprawnień, upewnij się, że do użytkownika wykonującego polecenia wdrożenia są przypisane odpowiednie role uprawnień.

Umieść funkcje kolejki zadań w kolejce

Funkcje kolejki zadań można dodawać do kolejki zadań w Cloud Tasks z zaufanego środowiska serwera, takiego jak Cloud Functions dla Firebase, za pomocą pakietu Firebase Admin SDK dla Node.js. Jeśli dopiero zaczynasz korzystać z pakietów Admin SDK, przeczytaj artykuł Dodawanie Firebase do serwera.

W typowym procesie pakiet Admin SDK tworzy nowe zadanie, dodaje je do kolejki w Cloud Tasks i ustawia jego konfigurację:

exports.enqueueBackupTasks = functions.https.onRequest(
async (_request, response) => {
  const queue = getFunctions().taskQueue("backupApod");
  const enqueues = [];
  for (let i = 0; i <= 10; i += 1) {
    // Enqueue each task with i*60 seconds delay. Our task queue function
    // should process ~1 task/min.
    const scheduleDelaySeconds = i * 60 
    enqueues.push(
        queue.enqueue(
          { id: `task-${i}` },
          {
            scheduleDelaySeconds,
            dispatchDeadlineSeconds: 60 * 5 // 5 minutes
          },
        ),
    );
  }
  await Promise.all(enqueues);
  response.sendStatus(200);

});
  • scheduleDelaySeconds: przykładowy kod próbuje rozłożyć wykonywanie zadań przez powiązanie n-tego zadania z n-tym zadaniem. Przekłada się to na aktywowanie ok. 1 zadania na minutę. Pamiętaj, że możesz też użyć scheduleTime, jeśli chcesz, aby usługa Cloud Tasks aktywowała zadanie w określonym momencie.
  • dispatchDeadlineSeconds: maksymalny czas oczekiwania na zakończenie zadania przez Cloud Tasks. Cloud Tasks spróbuje ponownie wykonać zadanie po konfiguracji ponownej konfiguracji kolejki lub do momentu osiągnięcia tego terminu. W przykładzie kolejka jest skonfigurowana tak, aby ponawiać próby wykonania zadania maksymalnie 5 razy, ale jeśli cały proces (w tym kolejne próby) trwa dłużej niż 5 minut, jest ono automatycznie anulowane.

Rozwiązywanie problemów

Włączanie logowania w Cloud Tasks

Logi z Cloud Tasks zawierają przydatne informacje diagnostyczne, takie jak stan żądania powiązanego z zadaniem. Domyślnie logi Cloud Tasks są wyłączone ze względu na duże ilości logów, które może ona potencjalnie generować w projekcie. Zalecamy włączenie dzienników debugowania w czasie, gdy aktywnie tworzysz i debugujesz funkcje kolejki zadań. Zobacz Włączanie rejestrowania.

Uprawnienia

Podczas dodawania zadań do kolejki lub gdy Cloud Tasks próbuje wywołać funkcje kolejki zadań, mogą wystąpić błędy PERMISSION DENIED. Sprawdź, czy projekt ma te powiązania uprawnień:

  • Tożsamość używana do umieszczania zadań w kolejce w Cloud Tasks wymaga uprawnienia cloudtasks.tasks.create.

    W przykładzie jest to domyślne konto usługi App Engine.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • Tożsamość używana do dodawania zadań do kolejki zadań w Cloud Tasks wymaga uprawnień do korzystania z konta usługi powiązanego z zadaniem w Cloud Tasks.

    W przykładzie jest to domyślne konto usługi App Engine.

Instrukcje dodawania domyślnego konta usługi App Engine jako użytkownika domyślnego konta usługi App Engine znajdziesz w dokumentacji Google Cloud IAM.

  • Tożsamość używana do aktywowania funkcji kolejki zadań wymaga uprawnienia cloudfunctions.functions.invoke.

    W przykładzie jest to domyślne konto usługi App Engine.

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