Ponów próbę użycia funkcji asynchronicznych

Z tego dokumentu dowiesz się, jak zażądać asynchronicznych (innych niż HTTPS) funkcji w tle, aby ponawiać próby w przypadku awarii.

Semantyka ponawiania

Cloud Functions gwarantuje co najmniej raz wykonanie funkcji opartej na zdarzeniach w przypadku każdego zdarzenia wywoływanego przez źródło zdarzeń. Domyślnie, jeśli wywołanie funkcji zakończy się z powodu błędu, funkcja nie zostanie wywołana ponownie, a zdarzenie zostanie pominięte. Gdy włączysz ponawianie prób w funkcji opartej na zdarzeniach, Cloud Functions będzie ponawiać nieudane wywołania funkcji, aż się ona zakończy lub upłynie okres ponawiania prób.

W przypadku funkcji 2 generacji ten okres ponawiania prób wygasa po 24 godzinach. W przypadku funkcji 1 generacji wygasa on po 7 dniach. Cloud Functions ponawia próbę utworzenia nowo utworzonych funkcji opartych na zdarzeniach za pomocą strategii wycofywania wykładniczego, przy czym czas do ponowienia wzrasta o 10–600 sekund. Ta zasada jest stosowana do nowych funkcji przy pierwszym ich wdrożeniu. Nie obowiązuje wstecznie do istniejących funkcji, które zostały wdrożone po raz pierwszy przed wprowadzeniem zmian opisanych w tej informacji o wersji, nawet w przypadku ich ponownego wdrożenia.

Jeśli ponawianie prób nie jest włączone dla funkcji, która jest ustawieniem domyślnym, funkcja zawsze zgłasza, że została wykonana, a w jej logach mogą pojawiać się kody odpowiedzi 200 OK. Dzieje się tak nawet wtedy, gdy funkcja napotkała błąd. Aby mieć pewność, że Twoja funkcja napotyka błąd, odpowiednio zgłoś błędy.

Dlaczego funkcje oparte na zdarzeniach nie są wykonywane

W rzadkich przypadkach z powodu błędu wewnętrznego funkcja może zakończyć się przedwcześnie, a próba może zostać wykonana automatycznie, ale nie musi.

Zwykle funkcja oparta na zdarzeniach może nie zostać prawidłowo wykonana z powodu błędów zgłaszanych w samym kodzie funkcji. Możliwe przyczyny:

  • Funkcja zawiera błąd, a środowisko wykonawcze zgłasza wyjątek.
  • Podczas próby wykonania funkcji funkcja nie może nawiązać połączenia z punktem końcowym usługi lub przekroczyć limit czasu.
  • Ta funkcja celowo zgłasza wyjątek (np. jeśli parametr nie przejdzie weryfikacji).
  • Funkcja Node.js zwraca odrzuconą obietnicę lub przekazuje do wywołania zwrotnego wartość inną niż null.

W każdym z powyższych przypadków funkcja domyślnie przestaje wykonywać, a zdarzenie jest odrzucane. Aby ponowić próbę użycia funkcji w przypadku błędu, możesz zmienić domyślną zasadę ponawiania, konfigurując właściwość „Ponów próbę w przypadku niepowodzenia”. Powoduje to, że zdarzenie jest ponawiane wielokrotnie, aż działanie funkcji zakończy się powodzeniem lub upłynie czas oczekiwania na ponowną próbę.

Włączanie i wyłączanie ponownych prób

Konfigurowanie ponownych prób w konsoli GCP

Jeśli tworzysz nową funkcję:

  1. Na ekranie Utwórz funkcję wybierz Dodaj wyzwalacz i wybierz typ zdarzenia, które ma być wyzwalaczem funkcji.
  2. W panelu Aktywator Eventarc zaznacz pole wyboru Ponów próbę w przypadku niepowodzenia, aby włączyć ponawianie prób.

Jeśli aktualizujesz istniejącą funkcję:

  1. Na stronie Podsumowanie funkcji w Cloud Functions kliknij nazwę aktualizowanej funkcji, aby otworzyć ekran Szczegóły funkcji, a następnie wybierz Edytuj na pasku menu, aby wyświetlić panele aktywatorów HTTPS i Eventarc.
  2. Aby edytować ustawienia reguły, w panelu Wyzwalacz Eventarc kliknij ikonę edycji .
  3. W panelu Aktywator Eventarc zaznacz lub odznacz pole wyboru Ponów próbę w przypadku niepowodzenia, aby włączyć lub wyłączyć ponawianie prób.

Konfigurowanie ponownych prób z poziomu kodu funkcji

Dzięki Cloud Functions dla Firebase możesz włączyć ponowne próby w kodzie funkcji. Aby to zrobić dla funkcji działającej w tle, takiej jak functions.foo.onBar(myHandler);, użyj runWith i skonfiguruj zasadę awarii:

functions.runWith({failurePolicy: true}).foo.onBar(myHandler);

Ustawienie true w takiej postaci konfiguruje funkcję ponawiania prób w przypadku niepowodzenia.

Sprawdzone metody

W tej sekcji znajdziesz opis sprawdzonych metod używania ponownych prób.

Używaj ponawiania w celu obsługi błędów przejściowych

Funkcja jest ponawiana w sposób ciągły, aż do jej pomyślnego wykonania, więc trwałe błędy, takie jak błędy, należy wyeliminować z kodu w drodze testowania przed włączeniem kolejnych prób. Ponowne próby najlepiej sprawdzają się w przypadku przejściowych i przejściowych błędów, które z dużym prawdopodobieństwem mogą zostać rozwiązane podczas próby rozwiązania, takich jak niestabilny punkt końcowy usługi lub przekroczenie limitu czasu oczekiwania.

Ustaw warunek zakończenia, aby uniknąć zapętlenia

Sprawdzoną metodą jest zabezpieczenie funkcji przed ciągłym zapętleniem w przypadku ponownych prób. Możesz to zrobić, uwzględniając dobrze zdefiniowany warunek końcowy przed rozpoczęciem przetwarzania przez funkcję. Ta metoda działa tylko wtedy, gdy funkcja uruchamia się prawidłowo i może ocenić warunek końcowy.

Prostym, ale skutecznym sposobem jest odrzucanie zdarzeń z sygnaturami czasowymi sprzed pewnego czasu. Pomaga to uniknąć zbyt wielu wykonań, gdy błędy są trwałe lub trwają dłużej niż zwykle.

Na przykład ten fragment kodu odrzuca wszystkie zdarzenia starsze niż 10 sekund:

const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
  console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
  callback();
  return;
}

Korzystaj z usługi catch z obietnicami

Jeśli funkcja ma włączone ponawianie, każdy nieobsługiwany błąd spowoduje ponowną próbę. Upewnij się, że kod rejestruje wszystkie błędy, które nie powinny powodować ponownej próby.

Oto przykład, co należy zrobić:

return doFooAsync().catch((err) => {
    if (isFatal(err)) {
        console.error(`Fatal error ${err}`);
    }
    return Promise.reject(err);
});

Ustaw powtarzającą się funkcję funkcji opartych na zdarzeniach jako idempotentna

Funkcje oparte na zdarzeniach, które można wykonać ponownie, muszą być idempotentne. Oto ogólne wytyczne dotyczące tworzenia idempotentności takiej funkcji:

  • Wiele zewnętrznych interfejsów API (np. Stripe) umożliwia podawanie klucza idempotentności jako parametru. Jeśli używasz takiego interfejsu API, jako klucza idempotentności użyj identyfikatora zdarzenia.
  • Idempotentność sprawdza się w przypadku dostawy co najmniej raz, ponieważ umożliwia bezpieczne ponowienie próby. Zatem ogólną sprawdzoną metodą pisania wiarygodnego kodu jest połączenie funkcji idempotentności z ponawianiem prób.
  • Upewnij się, że kod jest wewnętrznie idempotentny. Na przykład:
    • Upewnij się, że mutacje mogą wystąpić więcej niż raz bez zmiany wyniku.
    • Zapytanie o stan bazy danych w transakcji przed zmianą stanu.
    • Upewnij się, że wszystkie efekty uboczne są idempotentne.
  • nakładanie kontroli transakcyjnej poza funkcją, niezależnie od kodu; Może to być np. informacja, że dany identyfikator zdarzenia został już przetworzony.
  • radzić sobie ze powielonymi wywołaniami funkcji poza zakresem, Możesz na przykład zastosować osobny proces czyszczenia po zduplikowanych wywołaniach funkcji.

Skonfiguruj zasadę ponawiania

W zależności od potrzeb funkcji w Cloud Functions możesz bezpośrednio skonfigurować zasadę ponawiania próby. Dzięki temu możesz skonfigurować dowolną kombinację tych elementów:

  • Skróć okno ponownej próby z 7 dni do zaledwie 10 minut.
  • Zmień minimalny i maksymalny czas do ponowienia dla strategii ponawiania wzrastającego czasu do ponowienia.
  • Zmień strategię ponawiania prób, aby ponowić próbę natychmiast.
  • Skonfiguruj temat niedostarczonych komunikatów.
  • Ustaw maksymalną i minimalną liczbę prób dostarczenia.

Aby skonfigurować zasadę ponawiania:

  1. Napisz funkcję HTTP.
  2. Utwórz subskrypcję Pub/Sub za pomocą interfejsu Pub/Sub API, podając jako miejsce docelowe adres URL funkcji.

Więcej informacji o bezpośrednim konfigurowaniu Pub/Sub znajdziesz w dokumentacji Pub/Sub na temat obsługi błędów.