Che tu stia sviluppando un'app nascente o gestisca già un servizio ad alto traffico, puoi trarre vantaggio dalle informazioni e dai consigli di questa guida su come eseguire facilmente la scalabilità con FCM. Questi concetti e queste pratiche possono aiutarti a evitare impatti negativi quando devi inviare grandi volumi di messaggi.
Termini e concetti chiave
Richiesta di messaggio: una richiesta di messaggio FCM; utilizzata in modo intercambiabile con "richiesta", "messaggio" o "query".
Richieste al secondo (RPS): una metrica per descrivere la frequenza delle richieste in arrivo a FCM; utilizzata in modo intercambiabile con Query al secondo (QPS).
Token di quota, bucket di token e ricariche: quando invii messaggi all'API FCM HTTP v1, ogni richiesta consuma un token di quota allocato in un determinato intervallo di tempo. Questa finestra, chiamata "Token Bucket", si ricarica al termine della finestra temporale. Ad esempio, l'API HTTP v1 assegna 600.000 token quota per ogni secchio di token di 1 minuto, che si riempie completamente alla fine di ogni finestra di 1 minuto.
Limitazione lato server: quando il volume di traffico supera la capacità del servizio FCM, le richieste che superano la capacità di pubblicazione vengono rifiutate per limitare la frequenza del flusso in entrata. Potrebbero essere restituite risposte di errore 429
con intestazioni retry-after
per indicare
che devi attendere un determinato periodo di tempo prima di riprovare a inviare la richiesta.
Ritardo lato client: quando i client rilevano errori di richiesta, latenza elevata o errori 429
, devono limitare volontariamente la frequenza del flusso in uscita per evitare di aggravare la congestione.
Backoff esponenziale: quando riprovi a eseguire un'operazione in seguito a un errore, aggiungi ritardi di tempo in aumento esponenziale. Ad esempio: 1 s, 2 s, 4 s, 8 s, 16 s, 32 s e così via.
Jitter: evita di ripetere le richieste a intervalli esatti. Con il jitter, vari i ritardi di ripetizione tramite un processo casuale per distribuirli uniformemente nel tempo (ad esempio: 0,9 s, 2,3 s, 4,1 s, 8,5 s, 17,9 s, 34,7 s).
Amplificazione dei tentativi: quando le richieste non riuscite vengono ripetute senza backoff/jitter esponenziali, spesso si accumulano e si aggiungono al carico del traffico in corso, potenzialmente "amplificando" ed esacerbando i problemi di congestione del traffico.
Il problema: picchi di traffico
FCM elabora milioni di richieste al secondo (RPS). I picchi di traffico sono il principale fattore che contribuisce a provocare congestione sistemiche, problemi di latenza e interruzioni del servizio.
Che cos'è il traffico irregolare?
Esistono diversi tipi di picchi di traffico.
Picchi all'ora: FCM riceve più del doppio del traffico durante i primi 30 secondi fino a 2 minuti di ogni ora. Picchi simili, anche se minori, si osservano anche alle mezze ore e ai quarti d'ora (esempi: 00:15, 00:30, 00:45)
Amplificazione delle ripetizioni: la ripetizione delle richieste non riuscite o con timeout senza ritiro esponenziale può accumularsi in ondate ripetute di traffico oltre ai picchi di traffico esistenti.
Modifiche improvvise del modello di traffico: indirizzare il nuovo traffico a FCM o spostarlo in FCM tra regioni senza fattori di smorzamento come l'aumento graduale può causare picchi.
Utilizzo dei token quota con caricamento anticipato: esaurire tutti i token quota all'inizio delle finestre quota anziché distribuire le richieste in modo uniforme nelle finestre quota creerà oscillazioni on-off difficili e costose da bilanciare.
Eventi speciali: picchi di traffico durante le festività (Capodanno) o gli eventi sportivi (Coppa del mondo FIFA).
Rimedi ai picchi di traffico "appiattando la curva"
Questa sezione descrive le strategie per attenuare i picchi di traffico, ove possibile, ovvero le strategie per "appiattire la curva".
Utilizza FCM solo per casi d'uso appropriati
In alcuni casi d'uso, l'utilizzo di FCM per inviare una notifica non è necessario o appropriato.
Ad esempio, per le notifiche degli eventi nel calendario, puoi pianificare un'attività locale nella tua app per visualizzare una notifica agli orari appropriati anziché inviarla dal server dell'app. Limita i messaggi FCM alle sincronizzazioni del calendario.
Evita picchi
Un antipattern di scalabilità consiste nell'inviare notifiche FCM il più rapidamente possibile, anziché applicare la limitazione lato server. Considera quanto segue:
- Tutti i tuoi clienti devono ricevere la stessa notifica entro un intervallo di 1 minuto? Ad esempio, una finestra di consegna di 5 minuti soddisferebbe comunque le esigenze della tua attività?
- I tuoi clienti possono essere segmentati in base alla priorità per attenuare i picchi?
- Le notifiche possono essere programmate in anticipo?
Se possibile: evita strategie che comportano l'esaurimento immediato della quota di invio di FCM, per poi ripetere il pattern non appena il bucket di token si riempie di nuovo. Questo schema di accesso crea problemi di bilanciamento del carico per FCM e per i relativi sistemi dipendenti. Aumenta il traffico il più gradualmente possibile. Come minimo, aumenta da 0 al valore RPS massimo in un intervallo di tempo di 60 secondi. Preferisci finestre più lunghe per un RPS più elevato.
Evitare il traffico "sull'ora"
Se possibile: evita di inviare messaggi entro 2 minuti da ogni interruzione di 00, 15, 30 e 45 minuti.
Implementare la limitazione lato server
Implementa la limitazione lato server per monitorare e gestire il flusso di traffico verso FCM.
Gestione dei nuovi tentativi
Sebbene FCM si impegni a garantire un'elevata disponibilità, a volte alcune richieste scadono o non riescono. Sebbene i motivi siano diversi, le seguenti best practice ottimizzano il comportamento di ripetizione per inviare i messaggi il prima possibile riducendo al minimo l'impatto sulla congestione del traffico.
Timeout
Imposta un timeout di almeno 10 secondi per le richieste di invio prima di ritentare. La maggior parte delle chiamate di procedura remota interne di FCM utilizza un timeout di 10 secondi.
Errori
- Per gli errori 400, 401, 403, 404: interrompi l'operazione e non riprovare.
- Per gli errori 429: riprova dopo aver atteso la durata impostata nell'intestazione retry-after. Se non è impostata l'intestazione retry-after, il valore predefinito è 60 secondi.
- Per gli errori 500: riprova con il backoff esponenziale.
Backoff esponenziale
Per evitare l'amplificazione dei tentativi, implementa il backoff экспоненциальный con jitter per le richieste di ripetizione. L'SDK Firebase Admin, ad esempio, implementa il backoff esponenziale.
Ecco altre impostazioni consigliate:
- Intervallo minimo: non riprovare immediatamente una richiesta non riuscita con FCM. Attendi almeno 10 secondi prima di riprovare una richiesta non riuscita.
- Intervallo massimo: imposta un intervallo massimo per l'eliminazione delle richieste che non sono più tempestive, anziché riprovare a tempo indeterminato.
Se una richiesta viene ripetuta continuamente con backoff esponenziale e continua a non riuscire 60 minuti dopo, è classificata erroneamente come errore ripetibile o FCM sta riscontrando un'interruzione del servizio in cui i tentativi di nuovo accesso potrebbero aggravare inavvertitamente la situazione.
Crea piani di implementazione e rollback e apporta modifiche graduali
Quando apporti modifiche al traffico su larga scala, ad esempio aumenti il traffico verso FCM o lo sposti tra regioni o reti, progettare un piano di implementazione/ripristino e implementare modifiche graduali proteggerà i tuoi utenti, il tuo servizio e FCM.
- Un piano di implementazione allinea le aspettative degli stakeholder. In alcune situazioni (discusse di seguito), ti consigliamo di condividere in anticipo il tuo piano di implementazione con il team di FCM per evitare sorprese.
- Un piano di rollback ti consente di tenere conto delle contingenze e di preparare meccanismi per recuperare in modo rapido e sicuro da errori imprevisti.
- Le modifiche graduali hanno due aspetti:
- Aumenti "a gradini": i passaggi devono essere 1% -> 5% -> 10% -> 25% -> 50% -> 75% -> 100% o più precisi. "Soak" (osserva il comportamento del sistema sotto carico) ogni passaggio per 1 giorno o 1 settimana. In questo modo, puoi individuare potenziali problemi prima del passaggio al livello successivo.
- Aumento graduale del traffico: quando esegui ogni "passaggio" per aumentare il traffico, riducilo nell'arco di almeno un'ora. In questo modo, l'infrastruttura di bilanciamento del carico di FCM può scalare il nuovo traffico in modo appropriato, riducendo al minimo la possibilità di hotspot e congestione.
Ecco uno scenario ipotetico per la migrazione di 500.000 RPS a livello globale dall'API HTTP FCM precedente all'API HTTP FCM v1:
Settimana | Step | Strategia di applicazione graduale |
---|---|---|
0 | Aumento graduale dell'1% | Aumenta gradualmente da 0 a 5000 RPS a FCM HTTP v1 nell'arco di un'ora. |
1 | Aumento graduale del 5% | Aumenta gradualmente da 5000 a 25000 RPS nell'arco di 2 ore. |
2 | Applicazione graduale del 10% | Aumento graduale da 25.000 a 50.000 richieste al secondo in 2 ore |
3 | Applicazione graduale del 25% | Aumento da 50.000 a 125.000 richieste al secondo in 3 ore |
4 | Applicazione graduale del 50% | Aumento da 125.000 a 250.000 richieste al secondo in 6 ore |
5 | Applicazione graduale del 75% | Aumento da 250.000 a 375.000 richieste al secondo in 6 ore |
6 | Applicazione graduale al 100% | Aumento da 375.000 a 500.000 RPS in 6 ore |
Piano di rollback ipotetico:
- Se la latenza del 95° percentile aumenta a più di 500 ms o se il rapporto di errore supera l'1% per più di un'ora in qualsiasi passaggio, utilizza la configurazione dinamica per eseguire immediatamente il rollback al passaggio precedente.
- Continua a eseguire il rollback ai passaggi precedenti finché la latenza e il rapporto di errori non tornano ai livelli nominali.
Quando contattare FCM
Contatta FCM tramite l'assistenza Firebase se si verifica una delle seguenti condizioni:
- Le quote predefinite non soddisfano più il tuo caso d'uso
- Stai modificando i pattern di invio in un periodo di 3 mesi su una scala di 100.000 RPS a livello globale o 30.000 RPS a livello continentale.