L'API Google Ads applica la limitazione di frequenza in base alle query al secondo (QPS) sia agli ID cliente sia ai progetti Google Cloud in modo indipendente. Oltre alle richieste al minuto (che misurano la frequenza delle chiamate API), l'API Google Ads applica anche limiti alle operazioni al minuto (che misurano il numero totale di operazioni API tra le richieste). L'API Google Ads utilizza un algoritmo token bucket per misurare le richieste e determinare un limite di QPS appropriato, pertanto il limite esatto varia in base al carico complessivo del server in un determinato momento.
Lo scopo dell'imposizione di limiti di frequenza è impedire a un utente di interrompere il servizio per altri utenti (intenzionalmente o meno) sovraccaricando i server dell'API Google Ads con un volume elevato di richieste.
Le richieste che violano i limiti di frequenza vengono rifiutate con l'errore:
RESOURCE_TEMPORARILY_EXHAUSTED.
Puoi assumere il controllo della tua app e mitigare le limitazioni di frequenza riducendo attivamente il numero di richieste e limitando le QPS dal lato client.
Esistono diversi modi per ridurre le probabilità di superare il limite di frequenza. Acquisire familiarità con i concetti di Enterprise Integration Patterns (EIP), come messaggistica, riconsegna e limitazione, può aiutarti a creare un'app client più solida.
Le seguenti best practice sono ordinate per complessità, con le strategie più semplici in alto e le architetture più robuste, ma sofisticate, di seguito:
- Backoff esponenziale
- Limita le attività simultanee
- Creazione di richieste batch
- Limitatori di frequenza e limitazione
- Inserimento in coda
Backoff esponenziale
Quando la tua applicazione riceve un errore RESOURCE_TEMPORARILY_EXHAUSTED, utilizza una policy di backoff esponenziale con jitter randomizzato prima di riprovare la richiesta non riuscita. Il backoff esponenziale aumenta progressivamente il tempo di attesa tra i nuovi tentativi (ad esempio, attendendo 2 secondi, poi 4 secondi, poi 8 secondi, più un piccolo ritardo casuale), consentendo il recupero del carico del server e dei bucket di quota, impedendo al contempo picchi di nuovi tentativi sincronizzati tra le istanze client.
Limita le attività simultanee
Una causa principale del superamento dei limiti di frequenza è che l'app client genera un numero eccessivo di attività parallele. Sebbene non limitiamo il numero di richieste parallele che un'app client può avere, questo può superare il limite di richieste al secondo a livello di progetto Google Cloud.
Ti consigliamo di impostare un limite superiore ragionevole per il numero totale di attività simultanee che effettueranno richieste (in tutti i processi e le macchine) e di aumentarlo per ottimizzare il throughput senza superare il limite di frequenza.
Inoltre, puoi valutare la possibilità di limitare le QPS dal lato client (consulta Limitazione e limitatori di frequenza).
Creazione di richieste batch
Valuta la possibilità di raggruppare più operazioni in un'unica richiesta. Questo è più applicabile alle chiamate Mutate per vari servizi. Ad esempio, se aggiorni lo stato di più istanze di AdGroupAd, puoi chiamare MutateAdGroupAds una volta e passare più operations invece di chiamare MutateAdGroupAds una volta per ogni AdGroupAd. Per ulteriori esempi, consulta le nostre indicazioni sulle operazioni batch.
Sebbene l'invio di richieste batch riduca il numero totale di chiamate API e mitighi i limiti di frequenza per le richieste al minuto, potrebbe attivare il limite di frequenza per le operazioni al minuto se esegui un numero elevato di operazioni su un singolo account.
Limitatori di frequenza e limitazione
Oltre a limitare il numero totale di thread nella tua applicazione, puoi anche implementare limitatori di frequenza lato client. In questo modo, tutti i thread dei tuoi processi, cluster o entrambi sono regolati da un limite di QPS specifico dal lato client.
Consulta Guava RateLimiter o implementa il tuo algoritmo token bucket per un ambiente in cluster. Ad esempio, puoi gestire i token in un datastore in memoria distribuito a bassa latenza come Redis o Memcached, in cui ogni client acquisisce e consuma un token prima di elaborare una richiesta. Se i token sono esauriti, il client attende che venga aggiunto il successivo gruppo di token.
Coda
Una coda di messaggi è la soluzione per la distribuzione del carico delle operazioni, controllando al contempo le frequenze delle richieste e dei consumer. Sono disponibili diverse opzioni di coda dei messaggi, alcune open source, altre proprietarie, e molte di queste possono funzionare con linguaggi diversi.
Quando utilizzi le code di messaggi, puoi avere più producer che inviano messaggi alla coda e più consumer che li elaborano. Le limitazioni possono essere implementate sul lato consumer limitando il numero di consumer simultanei o implementando limitatori di frequenza o limitatori per i producer o i consumer.
Ad esempio, se un consumer di messaggi rileva un errore di limitazione di frequenza, può restituire la richiesta alla coda con un ritardo di nuovo tentativo standardizzato (utilizzando il backoff esponenziale) e aggiornare un feedback loop di limitazione di frequenza condiviso in modo che tutti i consumer riducano automaticamente la frequenza di elaborazione durante il recupero dall'errore.