Niezależnie od tego, czy rozwijasz nową aplikację, czy zarządzasz usługą o dużym natężeniu ruchu, w tym przewodniku znajdziesz wskazówki i rekomendacje dotyczące płynnego skalowania za pomocą FCM. Te koncepcje i praktyki mogą pomóc Ci uniknąć negatywnych skutków, gdy musisz wysłać dużą liczbę wiadomości.
Kluczowe terminy i pojęcia
Message Request: żądanie wiadomości FCM; używane zamiennie z określeniami „request”, „message” lub „query”.
Żądania na sekundę (RPS): dane opisujące szybkość przychodzących żądań do FCM. Używane zamiennie z zapytaniami na sekundę (QPS).
Tokeny limitu, zasobniki tokenów i uzupełnianie: podczas wysyłania wiadomości za pomocą interfejsu FCM HTTP v1 API każde żądanie wykorzystuje przydzielony token limitu w danym przedziale czasu. To okno, zwane „zasobnikiem tokenów”, wypełnia się w całości na koniec okresu. Na przykład interfejs HTTP w wersji 1 przydziela 600 tys. tokenów limitu na każdy 1-minutowy zasobnik tokenów, który na koniec każdego 1-minutowego okna jest ponownie napełniany.
Ograniczanie przepustowości po stronie serwera: gdy natężenie ruchu przekracza pojemność usługi FCM, żądania wykraczające poza pojemność są odrzucane, aby ograniczyć przepływ danych przychodzących. 429 odpowiedzi o błędach z nagłówkami retry-after mogą być zwracane, aby wskazać, że przed ponowną próbą wysłania żądania należy odczekać określony czas.
Ograniczanie przepustowości po stronie klienta: gdy klienci zauważą błędy żądań, duże opóźnienia lub błędy 429, powinni dobrowolnie ograniczyć przepływ wychodzący, aby uniknąć pogorszenia zatoru.
Wzrastający czas do ponowienia: w przypadku ponawiania prób po wystąpieniu błędów dodawaj coraz dłuższe opóźnienia. Na przykład: 1 s, 2 s, 4 s, 8 s, 16 s, 32 s itd.
Jittering: unikanie ponawiania żądań w dokładnych odstępach czasu. W przypadku losowego opóźnienia ponawiania prób opóźnienia są zmieniane w sposób losowy, aby równomiernie rozłożyć je w czasie (np. 0,9 s, 2,3 s, 4,1 s, 8,5 s, 17,9 s, 34,7 s).
Wielokrotne próby: gdy nieudane żądania są ponawiane bez wycofywania się z wykładniczym wzrostem lub losowym opóźnieniem, często się kumulują i zwiększają bieżące obciążenie ruchem, co może „wzmacniać” i pogarszać problemy z przeciążeniem ruchu.
Problem: skoki ruchu
FCM przetwarza miliony żądań na sekundę (RPS). Największy wpływ na zatory systemowe, problemy z opóźnieniami i awarie mają nagłe wzrosty ruchu.

Co to jest nagły wzrost ruchu?
Istnieje kilka różnych rodzajów nagłych wzrostów ruchu.
Skoki o pełnych godzinach: w ciągu pierwszych 30 sekund do 2 minut każdej godziny FCM otrzymuje ponad 2-krotnie większy ruch. Podobne, choć mniejsze, skoki obserwuje się też w przypadku półgodzinnych i kwadransowych przedziałów czasu (np. 00:15, 00:30, 00:45).

Wielokrotne ponawianie prób: ponawianie nieudanych lub przekraczających limit czasu żądań bez wzrastającego czasu do ponowienia może powodować powtarzające się fale ruchu, które nakładają się na istniejące szczyty ruchu.

Nagłe zmiany wzorca ruchu: kierowanie nowego ruchu do FCM lub przenoszenie ruchu do FCM w różnych regionach bez czynników wygładzających, takich jak stopniowe zwiększanie, może powodować skoki.

Wykorzystywanie tokenów limitu z góry: wyczerpanie wszystkich tokenów limitu na początku okresów limitu zamiast równomiernego rozłożenia żądań w okresach limitu spowoduje powstawanie oscylacji włączania i wyłączania, które są trudne i kosztowne do równoważenia obciążenia.

Wydarzenia specjalne: gwałtowne wzrosty natężenia ruchu podczas świąt (Sylwester) lub wydarzeń sportowych (Mistrzostwa Świata w Piłce Nożnej FIFA).

Łagodzenie skoków ruchu przez „spłaszczanie krzywej”
W tej sekcji opisujemy strategie, które pozwalają wygładzić skoki ruchu tam, gdzie jest to możliwe – strategie „spłaszczania krzywej”.
Używaj atrybutu FCM tylko w odpowiednich przypadkach
W niektórych przypadkach użycia dostarczanie powiadomień za pomocą FCM nie jest konieczne ani odpowiednie.
Na przykład w przypadku powiadomień o wydarzeniach w kalendarzu możesz zaplanować w aplikacji zadanie lokalne, które będzie wyświetlać powiadomienia w odpowiednich momentach, zamiast wysyłać je z serwera aplikacji. Ogranicz wiadomości FCM do synchronizacji kalendarza.
Unikaj nagłych wzrostów
Jednym z przykładów nieprawidłowego skalowania jest wysyłanie powiadomień FCM tak szybko, jak pozwalają na to systemy, zamiast stosowania ograniczania przepustowości po stronie serwera. Pamiętaj o tych kwestiach:
- Czy wszyscy 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 można podzielić klientów na segmenty według priorytetu, aby wygładzić skoki?
- Czy powiadomienia można zaplanować z wyprzedzeniem?
W miarę możliwości: unikaj strategii, które powodują natychmiastowe wyczerpanie limitu wysyłania FCM, a następnie powtarzają ten wzorzec, gdy tylko zasobnik tokenów zostanie ponownie napełniony. Ten wzorzec dostępu powoduje problemy z równoważeniem obciążenia w przypadku FCM i zależnych od niego systemów. Zwiększaj ruch stopniowo. Przynajmniej zwiększaj liczbę żądań z 0 do maksymalnej wartości RPS w ciągu 60 sekund. Wybieraj dłuższe okna, aby uzyskać wyższą wartość RPS.
Unikanie ruchu „o pełnej godzinie”
W miarę możliwości: unikaj wysyłania wiadomości w ciągu 2 minut od każdej z godzin: 00, 15, 30 i 45.
Wdrażanie ograniczania liczby żądań po stronie serwera
Wdróż ograniczanie po stronie serwera, aby monitorować ruch do FCM i nim zarządzać.
Obsługa ponawiania prób
Chociaż FCM dąży do zapewnienia wysokiej dostępności, czasami niektóre żądania mogą przekroczyć limit czasu lub zakończyć się niepowodzeniem. Przyczyny mogą być różne, ale poniższe sprawdzone metody optymalizują ponawianie prób, aby dostarczać wiadomości jak najszybciej, a jednocześnie minimalizować wpływ na przeciążenie ruchu.
Czasy oczekiwania
Ustaw co najmniej 10-sekundowy limit czasu dla żądań wysyłania przed ponowną próbą. Większość wewnętrznych wywołań procedur zdalnych FCM ma 10-sekundowy limit czasu.
Błędy
- W przypadku błędów 400, 401, 403 i 404: przerwij i nie ponawiaj.
- W przypadku błędów 429: ponów próbę po odczekaniu czasu określonego w nagłówku retry-after. Jeśli nie ustawiono nagłówka retry-after, domyślna wartość to 60 sekund.
- W przypadku błędów 500: ponów próbę ze wzrastającym czasem do ponowienia.
Wzrastający czas do ponowienia
Aby uniknąć wzmocnienia ponawiania, w przypadku ponawiania żądań zastosuj wykładnicze wycofywanie z losowym opóźnieniem. Pakiet Firebase Admin SDK na przykład implementuje wzrastający czas do ponowienia.
Oto kilka dodatkowych zalecanych ustawień:
- Minimalny odstęp czasu: nie ponawiaj od razu nieudanej prośby za pomocą FCM. Przed ponowną próbą wykonania nieudanego żądania odczekaj co najmniej 10 sekund.
- 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 ze wzrastającym czasem do ponowienia i po 60 minutach nadal kończy się niepowodzeniem, oznacza to, że albo zostało błędnie zakwalifikowane jako błąd, który można rozwiązać ponownie, albo FCM ma awarię, w przypadku której ponawianie prób może nieumyślnie pogorszyć sytuację.
Tworzenie planów wdrażania i wycofywania oraz wprowadzanie stopniowych zmian
W przypadku wprowadzania zmian w ruchu na dużą skalę, np. zwiększania ruchu do FCM lub przenoszenia ruchu między regionami lub sieciami, opracowanie planu wdrażania i wycofywania zmian oraz wprowadzanie stopniowych zmian pomoże chronić użytkowników, usługę i FCM.
- Plan wdrożenia pozwala określić oczekiwania zainteresowanych stron. W niektórych sytuacjach (omówionych poniżej) warto wcześniej udostępnić plan wdrożenia zespołowi FCM, aby uniknąć niespodzianek.
- Plan wycofania umożliwia uwzględnienie nieprzewidzianych okoliczności i przygotowanie mechanizmów szybkiego i bezpiecznego przywracania systemu po nieoczekiwanych awariach.
- Wprowadzanie stopniowych zmian ma 2 aspekty:
- Stopniowe zwiększanie: kroki powinny wynosić 1% –> 5% –> 10% –> 25% –> 50% –> 75% –> 100% lub więcej. „Soak” (obserwuj zachowanie systemu pod obciążeniem) na każdym etapie przez 1 dzień do 1 tygodnia. Dzięki temu możesz wykryć potencjalne problemy przed kolejnym „awansowaniem”.
- Stopniowe zwiększanie ruchu: podczas każdego „kroku” zwiększania ruchu rozłóż go równomiernie na co najmniej godzinę. Dzięki temu infrastruktura równoważenia obciążenia FCM może odpowiednio skalować nowy ruch, minimalizując potencjalne występowanie hotspotów i zatorów.
Oto hipotetyczny scenariusz migracji 500 tys. żądań na sekundę na całym świecie ze starszego interfejsu HTTP API FCM na interfejs HTTP API FCM w wersji 1:
| Tydzień | Step | Strategia stopniowego zwiększania stawek |
|---|---|---|
| 0 | 1% wzrostu | W ciągu godziny stopniowo zwiększaj liczbę żądań z 0 do 5000 na sekundę w przypadku interfejsu FCM HTTP v1. |
| 1 | 5% zwiększanie wyświetlania | Stopniowo zwiększaj liczbę żądań z 5000 do 25 000 RPS w ciągu 2 godzin. |
| 2 | 10% zwiększanie wyświetlania | Płynne zwiększanie liczby żądań na sekundę z 25 tys. do 50 tys. w ciągu 2 godzin |
| 3 | 25% wzrost | Zwiększanie liczby żądań z 50 tys. do 125 tys. RPS w ciągu 3 godzin |
| 4 | 50% wzrost | Zwiększanie liczby żądań z 125 tys. do 250 tys. na godzinę w ciągu 6 godzin |
| 5 | 75% wzrostu | Zwiększanie liczby żądań z 250 tys. do 375 tys. na godzinę w ciągu 6 godzin |
| 6 | 100% zwiększenie wyświetlania | Zwiększanie liczby żądań z 375 tys. do 500 tys. na sekundę w ciągu 6 godzin |
Przykładowy plan wycofania zmian:
- Jeśli w dowolnym kroku opóźnienie na poziomie 95 percentyla wzrośnie do ponad 500 ms lub współczynnik błędów przekroczy 1% na ponad godzinę, użyj konfiguracji dynamicznej, aby natychmiast wycofać zmiany do poprzedniego kroku.
- Cofaj zmiany do wcześniejszych kroków, aż czas oczekiwania i odsetek błędów wrócą do nominalnych poziomów.
Kiedy skontaktować się z FCM
Skontaktuj się z FCM za pomocą zespołu pomocy Firebase, jeśli:
- Limity domyślne nie spełniają już Twoich wymagań
- Zmieniasz wzorce wysyłania w okresie 3 miesięcy w skali 100 tys. RPS na całym świecie lub 30 tys. RPS na kontynencie.