Najlepsze praktyki dotyczące wysyłania komunikatów FCM na dużą skalę

Niezależnie od tego, czy tworzysz nową aplikację, czy już korzystasz z usługi o dużym natężeniu ruchu, możesz skorzystać ze spostrzeżeń i zaleceń zawartych w tym przewodniku na temat płynnego skalowania za pomocą FCM. Te koncepcje i praktyki mogą pomóc uniknąć negatywnych skutków, gdy trzeba wysłać dużą liczbę wiadomości.

Kluczowe terminy i pojęcia

Żądanie wiadomości : żądanie wiadomości FCM; używane zamiennie z „prośbą”, „wiadomością” lub „zapytaniem”.

Liczba żądań na sekundę (RPS) : metryka opisująca liczbę żądań przychodzących do FCM; używane zamiennie z liczbą zapytań na sekundę (QPS).

Tokeny przydziału, zbiorcze tokeny i uzupełnienia : podczas wysyłania wiadomości za pośrednictwem interfejsu API FCM HTTP v1 każde żądanie zużywa przydzielony token przydziału w danym przedziale czasowym. To okno, zwane „ Wiadro żetonów ”, uzupełnia się do pełna na koniec okna czasowego. Na przykład: interfejs API protokołu HTTP v1 przydziela 600 000 tokenów przydziału na każdy 1-minutowy zasobnik tokenów, który jest uzupełniany do pełna na koniec każdego 1-minutowego okna.

Ograniczanie po stronie serwera : gdy natężenie ruchu przekracza pojemność usługi FCM, żądania przekraczające pojemność są odrzucane, aby ograniczyć przepływ danych przychodzących. Może zostać zwróconych 429 odpowiedzi na błędy z nagłówkami retry-after , aby wskazać, że należy odczekać określony czas przed ponowieniem żądania.

Ograniczanie po stronie klienta : gdy klienci zaobserwują niepowodzenia żądań, duże opóźnienia lub błędy 429 , powinni dobrowolnie ograniczyć przepływ wychodzący, aby uniknąć zaostrzenia zatorów.

Wykładnicze wycofywanie : podczas ponawiania błędów dodaj wykładniczo rosnące opóźnienia czasowe. Na przykład: 1s, 2s, 4s, 8s, 16s, 32s.

Jittering : Unikanie ponawiania żądań w dokładnych odstępach czasu. W przypadku drgań można zmieniać opóźnienia ponownych prób w procesie losowym, aby rozłożyć je równomiernie w czasie (na przykład: 0,9 s, 2,3 s, 4,1 s, 8,5 s, 17,9 s, 34,7 s).

Wzmocnienie ponownych prób : gdy ponawiane są nieudane żądania bez wykładniczego wycofywania/jitterowania, często kumulują się one i zwiększają bieżące obciążenie ruchem, potencjalnie „wzmacniając” i zaostrzając problemy z zatorami w ruchu.

Problem: skoki ruchu

FCM przetwarza miliony żądań na sekundę (RPS). Największą przyczyną zatorów systemowych, problemów z opóźnieniami i przestojów są skoki ruchu.

Wykres liniowy przedstawiający wzrost ruchu w nieregularnych odstępach czasu.

Co to jest ruch kolczysty?

Istnieje kilka różnych rodzajów skoków ruchu.

Skoki co godzinę: FCM otrzymuje ponad dwukrotnie większy ruch w ciągu pierwszych 30 sekund do 2 minut każdej godziny. Podobne, choć mniejsze, skoki obserwuje się również w punktach półgodzin i kwadransów (przykłady: 00:15, 00:30, 00:45)

Wykres liniowy przedstawiający półgodzinne i ćwierćgodzinne trendy wzrostowe.

Wzmocnienie ponownych prób : ponawianie nieudanych lub przekroczonych żądań bez wykładniczego wycofywania może kumulować się w powtarzające się fale ruchu na istniejących szczytach ruchu.

Wykres liniowy przedstawiający rosnące wzorce skoków.

Nagłe zmiany wzorca ruchu: kierowanie nowego ruchu do FCM lub przenoszenie ruchu do FCM między regionami bez czynników łagodzących, takich jak stopniowe zwiększanie ruchu, może powodować skoki.

Wykres liniowy przedstawiający jeden nagły skok.

Użycie tokenów przydziału z wyprzedzeniem: wyczerpanie wszystkich tokenów przydziałów na początku okien przydziałów zamiast równomiernego rozłożenia żądań w oknach przydziałów spowoduje wahania włączenia i wyłączenia, które są trudne i kosztowne w równoważeniu obciążenia.

Wykres liniowy przedstawiający bardzo ostry skok.

Wydarzenia specjalne: Skoki ruchu w okresie świąt (Sylwester) lub wydarzeń sportowych ( Puchar Świata FIFA ).

Wykres liniowy przedstawiający wiele powtarzających się skoków.

Zaradzić skokom ruchu poprzez „spłaszczenie krzywej”

W tej sekcji opisano strategie łagodzenia skoków ruchu, tam gdzie to możliwe — strategie mające na celu „spłaszczenie krzywej”.

Używaj FCM tylko w odpowiednich przypadkach użycia

Istnieją pewne przypadki użycia, w których użycie FCM do dostarczenia powiadomienia nie jest konieczne ani właściwe.

Na przykład w przypadku powiadomień o wydarzeniach w kalendarzu możesz zaplanować w aplikacji zadanie lokalne, aby wyświetlało powiadomienie w odpowiednim czasie zamiast wysyłać je z serwera aplikacji. Ogranicz wiadomości FCM do synchronizacji kalendarza.

Unikaj kolców

Jednym z antywzorców skalowania jest wysyłanie powiadomień FCM tak szybko, jak pozwalają na to systemy, zamiast stosowania ograniczania przepustowości po stronie serwera. Rozważ następujące:

  • Czy wszyscy Twoi klienci muszą otrzymać to samo powiadomienie w ciągu 1 minuty? Czy na przykład 5-minutowe okno dostawy nadal spełniałoby Twoje potrzeby biznesowe?
  • Czy Twoi klienci mogą być segmentowani na podstawie priorytetu, aby złagodzić skoki cen?
  • Czy powiadomienia można zaplanować z wyprzedzeniem?

O ile to możliwe : unikaj strategii, które powodują natychmiastowe wyczerpanie limitu wysyłania FCM, tylko powtarzaj wzór, gdy tylko uzupełni się Twój zasobnik tokenów. Ten wzorzec dostępu stwarza problemy z równoważeniem obciążenia dla FCM i systemów od niego zależnych. Zwiększaj ruch tak stopniowo, jak to możliwe. Co najmniej rampa od 0 do maksymalnego RPS w 60-sekundowym oknie czasowym. Preferuj dłuższe okna, aby uzyskać wyższy RPS.

Unikaj ruchu całodobowego

Jeśli to możliwe : unikaj wysyłania wiadomości w ciągu 2 minut od każdego ze znaczników: 00, :15, :30 i :45 minut.

Zaimplementuj ograniczanie przepustowości po stronie serwera

Wdrażaj ograniczanie przepustowości po stronie serwera, aby monitorować i zarządzać przepływem ruchu do FCM.

Obsługa ponownych prób

Chociaż FCM stara się zapewnić wysoką dostępność, czasami niektóre żądania przekraczają limit czasu lub kończą się niepowodzeniem. Chociaż przyczyny są różne, poniższe najlepsze praktyki optymalizują zachowanie ponownych prób, aby dostarczać wiadomości tak szybko, jak to możliwe, minimalizując jednocześnie wpływ na zatory w ruchu.

Limity czasu

Ustaw co najmniej 10-sekundowy limit czasu dla żądań wysyłania przed ponowną próbą. Większość wewnętrznych zdalnych wywołań procedur FCM korzysta z 10-sekundowego limitu czasu.

Błędy

  • W przypadku błędów 400, 401, 403, 404: przerwij i nie próbuj ponownie.
  • W przypadku błędów 429: spróbuj ponownie po odczekaniu czasu ustawionego w nagłówku ponownej próby. Jeśli nie ustawiono nagłówka ponownej próby, wartość domyślna to 60 sekund.
  • W przypadku błędów 500: spróbuj ponownie z wykładniczym wycofywaniem.

Wykładniczy zwrot

Aby uniknąć wzmocnienia ponownych prób, zaimplementuj wykładnicze wycofywanie z fluktuacją w przypadku żądań ponawiania prób. Na przykład pakiet Firebase Admin SDK implementuje wykładnicze wycofywanie.

Oto kilka innych zalecanych ustawień:

  • Minimalny odstęp: Nie ponawiaj natychmiast nieudanego żądania za pomocą FCM. Odczekaj co najmniej 10 sekund przed ponowną próbą nieudanego żądania.
  • Maksymalny interwał: Ustaw maksymalny interwał dla odrzucania żądań, które nie są już aktualne, zamiast ponawiać próby w nieskończoność.

Jeśli żądanie jest stale ponawiane z wykładniczym wycofywaniem i po 60 minutach nadal kończy się niepowodzeniem, jest albo błędnie klasyfikowane jako błąd możliwy do ponowienia, albo w FCM występuje awaria, której ponowne próby mogą nieumyślnie pogorszyć sytuację.

Twórz plany wdrażania i wycofywania oraz wprowadzaj stopniowe zmiany

W przypadku wprowadzania zmian w ruchu na dużą skalę, takich jak zwiększanie ruchu w FCM lub przenoszenie ruchu między regionami lub sieciami, zaprojektowanie planu wdrożenia/wycofania i wdrożenie stopniowych zmian ochroni Twoich użytkowników, Twoją usługę i FCM.

  • Plan wdrożenia dostosowuje oczekiwania interesariuszy. W niektórych sytuacjach (omówionych poniżej) możesz chcieć udostępnić swój plan wdrożenia z wyprzedzeniem zespołowi FCM, aby uniknąć niespodzianek.
  • Plan wycofywania zmian umożliwia uwzględnienie sytuacji awaryjnych i przygotowanie mechanizmów szybkiego i bezpiecznego odzyskiwania danych po nieprzewidzianych awariach.
  • Dokonywanie stopniowych zmian ma dwa aspekty:
    • Zwiększanie „krokowe”: Kroki powinny wynosić 1% -> 5% -> 10% -> 25% -> 50% -> 75% -> 100% lub mniej. „ Namocz ” (obserwuj zachowanie systemu pod obciążeniem) każdy krok przez 1 dzień do 1 tygodnia. Pozwala to wykryć potencjalne problemy przed kolejnym „step-upem”
    • Stopniowe zwiększanie ruchu: wykonując każdy „krok” w celu zwiększenia ruchu, należy go wygładzić w ciągu co najmniej godziny. Dzięki temu infrastruktura równoważenia obciążenia FCM może odpowiednio skalować nowy ruch, minimalizując jednocześnie ryzyko wystąpienia hotspotów i zatorów.

Oto hipotetyczny scenariusz globalnej migracji 500 000 RPS z interfejsu API FCM Legacy HTTP do interfejsu API FCM HTTP v1:

Tydzień Krok Strategia stopniowego zwiększania wydajności
0 Zwiększenie o 1%. Płynne zwiększanie prędkości od 0 do 5000 RPS do FCM HTTP v1 w ciągu godziny.
1 Podwyżka o 5%. Płynne zwiększanie prędkości z 5000 do 25 000 obr./s w ciągu 2 godzin.
2 Podwyżka o 10%. Płynne zwiększanie prędkości z 25 000 do 50 000 obr./s w ciągu 2 godzin
3 Zwiększenie o 25%. Wzrost z 50 000 do 125 000 RPS w ciągu 3 godzin
4 Zwiększenie o 50%. Wzrost ze 125 000 do 250 000 obr./s w ciągu 6 godzin
5 Wzrost o 75%. Wzrost z 250 000 do 375 000 obr./s w ciągu 6 godzin
6 100% rozrostu Wzrost z 375 000 do 500 000 obr./s w ciągu 6 godzin

Hipotetyczny plan wycofania:

  • Jeśli 95-percentylowe opóźnienie wzrośnie do ponad 500 ms lub jeśli współczynnik błędów przekroczy 1% przez ponad godzinę na dowolnym etapie, użyj konfiguracji dynamicznej, aby natychmiast wrócić do poprzedniego kroku.
  • Kontynuuj wycofywanie do wcześniejszych kroków, aż opóźnienie i współczynnik błędów powrócą do poziomów nominalnych.

Kiedy skontaktować się z FCM

Skontaktuj się z FCM za pośrednictwem pomocy technicznej Firebase , jeśli ma zastosowanie którakolwiek z poniższych sytuacji:

  • Domyślne limity nie spełniają już Twojego przypadku użycia
  • Zmieniasz swoje wzorce wysyłania w ciągu 3 miesięcy w skali 100 000 RPS na całym świecie lub 30 000 RPS na kontynencie.