L'API Google Ads applique une limitation du débit par requêtes par seconde (RPS) sur les ID client et les projets Google Cloud de manière indépendante. En plus des requêtes par minute (qui mesurent la fréquence des appels d'API), l'API Google Ads applique également des limites au nombre d'opérations par minute (qui mesurent le nombre total d'opérations d'API sur l'ensemble des requêtes). L'API Google Ads utilise un algorithme de token bucket pour mesurer les requêtes et déterminer une limite de RPS appropriée. La limite exacte varie donc en fonction de la charge globale du serveur à un moment donné.
L'objectif de ces limites est d'empêcher un utilisateur de perturber le service pour les autres utilisateurs en surchargeant (intentionnellement ou non) les serveurs de l'API Google Ads avec un volume élevé de requêtes.
Les requêtes qui ne respectent pas les limites de débit sont rejetées avec l'erreur RESOURCE_TEMPORARILY_EXHAUSTED.
Vous pouvez prendre le contrôle de votre application et atténuer les limites de débit en réduisant activement le nombre de requêtes et en limitant le nombre de requêtes par seconde côté client.
Il existe plusieurs façons de réduire les risques de dépassement de la limite de débit. Se familiariser avec les concepts des modèles d'intégration d'entreprise (EIP, Enterprise Integration Patterns) tels que la messagerie, la relivraison et la limitation peut vous aider à créer une application cliente plus robuste.
Les pratiques recommandées suivantes sont classées par ordre de complexité, avec les stratégies les plus simples en haut, suivies des architectures plus robustes, mais plus sophistiquées :
- Intervalle exponentiel entre les tentatives
- Limiter les tâches simultanées
- Effectuer des requêtes par lot
- Limitation et limiteurs de débit
- Mise en file d'attente
Intervalle exponentiel entre les tentatives
Lorsque votre application reçoit une erreur RESOURCE_TEMPORARILY_EXHAUSTED, utilisez une règle d'intervalle exponentiel entre les tentatives avec une gigue aléatoire avant de relancer la requête ayant échoué. L'intervalle exponentiel entre les tentatives augmente progressivement le temps d'attente entre les tentatives (par exemple, en attendant 2 secondes, puis 4 secondes, puis 8 secondes, plus un petit délai aléatoire). Cela permet à la charge du serveur et aux buckets de quota de récupérer, tout en évitant les pics de nouvelles tentatives synchronisées entre les instances client.
Limiter les tâches simultanées
L'une des causes principales du dépassement des limites de débit est que l'application cliente génère un nombre excessif de tâches parallèles. Bien que nous ne limitions pas le nombre de requêtes parallèles qu'une application cliente peut avoir, cela peut dépasser la limite de requêtes par seconde au niveau du projet Google Cloud.
Il est recommandé de définir une limite supérieure raisonnable pour le nombre total de tâches simultanées qui vont envoyer des requêtes (sur l'ensemble des processus et des machines), puis d'ajuster cette limite à la hausse pour optimiser votre débit sans dépasser la limite de débit.
En outre, vous pouvez envisager de limiter les RPS côté client (voir Limitation du débit et limiteurs de débit).
Effectuer des requêtes par lot
Envisagez de regrouper plusieurs opérations dans une seule requête. Cela s'applique principalement aux appels Mutate pour différents services. Par exemple, si vous mettez à jour l'état de plusieurs instances de AdGroupAd, vous pouvez appeler MutateAdGroupAds une fois et transmettre plusieurs operations au lieu d'appeler MutateAdGroupAds une fois pour chaque AdGroupAd. Pour obtenir d'autres exemples, consultez nos conseils sur les opérations par lot.
Bien que le traitement par lot des requêtes réduise le nombre total d'appels d'API et atténue les limites de débit pour les requêtes par minute, il peut déclencher la limite de débit pour les opérations par minute si vous effectuez un grand nombre d'opérations sur un seul compte.
Limitation et limiteurs de débit
En plus de limiter le nombre total de threads dans votre application, vous pouvez également implémenter des limiteurs de débit côté client. Cela garantit que tous les threads de vos processus, clusters ou les deux sont régis par une limite de RPS spécifique côté client.
Consultez la page Guava RateLimiter ou implémentez votre propre algorithme de token bucket pour un environnement en cluster. Par exemple, vous pouvez gérer les jetons dans un datastore en mémoire distribué à faible latence, tel que Redis ou Memcached, où chaque client acquiert et consomme un jeton avant de traiter une requête. Si les jetons sont épuisés, le client attend que le prochain lot de jetons soit réapprovisionné.
Mise en file d'attente
Une file d'attente de messages est la solution pour répartir la charge des opérations, tout en contrôlant les taux de requêtes et de consommateurs. Il existe un certain nombre d'options de file d'attente de messages, certaines Open Source, d'autres propriétaires, et beaucoup d'entre elles peuvent fonctionner avec différents langages.
Lorsque vous utilisez des files d'attente de messages, vous pouvez avoir plusieurs producteurs qui envoient des messages à la file d'attente et plusieurs consommateurs qui traitent ces messages. Les limitations peuvent être mises en œuvre côté consommateur en limitant le nombre de consommateurs simultanés, ou en mettant en œuvre des limiteurs de débit ou des limiteurs pour les producteurs ou les consommateurs.
Par exemple, si un consommateur de messages rencontre une erreur de limitation du débit, il peut renvoyer la requête à la file d'attente avec un délai avant nouvelle tentative standardisé (à l'aide d'un intervalle exponentiel entre les tentatives) et mettre à jour une boucle de rétroaction partagée du limiteur de débit afin que tous les consommateurs réduisent automatiquement leur taux de traitement tout en récupérant de l'erreur.