Manette des gaz et la file d'attente des requêtes à l'API en raison par seconde cap
Je suis l'utiliser mikeal/demande de faire des appels de l'API. L'une des API que j'utilise le plus souvent (le Shopify API). Récemment sortir une nouvelle appel limite, je vais voir des erreurs comme:
Exceeded 6.0 calls per second for api client. Slow your requests or contact support for higher limits.
J'ai déjà eu droit à une mise à niveau, mais quelle que soit la quantité de bande passante je se que je dois tenir compte de cela. Une grande majorité de la demande de la Shopify API sont dans async.map() fonctions de la boucle de requêtes asynchrones, et de recueillir les corps.
Je suis à la recherche d'aide, peut-être une bibliothèque qui existe déjà, qui tourne autour de la demande en module et en fait bloc, le sommeil, le gaz, l'attribution, la gestion, le nombre de demandes simultanées de tirer de manière asynchrone et de les limiter à dire 6
demandes à la fois. Je n'ai aucun problème à travailler sur un tel projet s'il n'existe pas. Je ne sais pas comment gérer ce genre de situation, et j'espère que pour certains type de standard.
J'ai fait un billet avec mikeal/demande.
- Pas de blague. J'ai finalement eu marre de la ElasticTranscoder de l'INTERFACE utilisateur et de construire le code à utiliser l'API via le JS SDK et instantanément frappé de ces limites.
- En 2018, il est taux d'-limiteur-flexible le paquet qui fait le travail
Vous devez vous connecter pour publier un commentaire.
J'ai couru dans le même problème avec les différentes Api. AWS est célèbre pour la limitation ainsi.
Un couple d'approches peuvent être utilisées. Vous avez mentionné asynchrone.map() fonction. Avez-vous essayé async.la file d'attente()? La file d'attente méthode devrait vous permettre de définir une solide limite (6) et rien de plus de ce montant sera placé dans la file d'attente.
Un autre outil utile est oibackoff. Cette bibliothèque vous permettra de l'interruption de votre demande si vous obtenez une erreur depuis le serveur et essayez à nouveau.
Il peut être utile d'envelopper les deux bibliothèques assurez-vous que vos deux bases sont couvertes: async.file d'attente pour vous assurer de ne pas aller dessus de la limite, et oibackoff pour vous assurer d'obtenir une autre chance de faire votre demande si le serveur vous dit il y a une erreur.
async.maps
sont répartis et imbriquées les unes dans les autres. Donc je ne peux pas il suffit de les remplacer avecasync.queue
parce que je ne serait toujours pas de garantie que les requêtes à l'API serait de 6 à la fois. Ils seraient 6 * chaqueasync.queue
. Mais je pense que la balle roule?Pour une solution alternative, j'ai utilisé le nœud-taux-limiteur de pour envelopper la fonction de demande comme ceci:
var limiter = new RateLimiter(6, 'second');
Elle est complémentaire à une solution comme oibackoff qui va changer de comportement après une limite de taux a été atteint.node-rate-limiter
vous appelle en arrière une fois que le jeton devient disponibleLa
npm
paquet simple-tarif-limiteur de semble être une très bonne solution à ce problème.En outre, il est plus facile à utiliser que
node-rate-limiter
etasync.queue
.Voici un extrait de code qui montre comment le fait de limiter les demandes à dix par seconde.
Dans async module, cette demande de fonctionnalité est fermé comme "l'habitude de fixer"
un problème difficile." Voir le côté droit de ici:
https://github.com/caolan/async/issues/1314
https://github.com/caolan/async/issues/37#issuecomment-14336237
Il y a une solution à l'aide de leakybucket ou token bucket modèle, il est mis en œuvre "limiteur" npm module RateLimiter.
RateLimiter
, voir l'exemple ici: https://github.com/caolan/async/issues/1314#issuecomment-263715550Un autre moyen est d'utiliser
PromiseThrottle
, j'ai utilisé cette, travail exemple ci-dessous:De sortie:
Nous pouvons clairement voir que le taux de sortie, c'est à dire 5 appels pour chaque seconde.
Voici ma solution utiliser une bibliothèque
request-promise
ouaxios
et encapsuler l'appel à cette promesse.Les autres solutions n'ont pas été à mon goût. Recherche en outre, j'ai trouvé promesse-ratelimit qui vous donne une api que vous pouvez simplement
await
:L'exemple ci-dessus va vous assurer que faire des requêtes sur
api.example.com
chaque 2000ms au plus. En d'autres termes, la première requête ne attendre 2000ms.Ma solution à l'aide de moyens modernes de vanille JS:
Utilisation: