9
votes

Limiter la demande de service Web simultanée (ou une approche par lots)

J'ai un pour la compréhension qui récupère une liste d'identité séparée par des virgules d'un service Web.
Ensuite, j'utilise la liste d'identité pour effectuer de nouveaux appels, mon problème ici est que la liste d'identité peut être d'environ 10 000 longs et chaque appel est un document XML de taille moyenne.
Le point final du service Web, ou peut-être le cadre de lecture, ne l'aime pas tout à fait lorsque je demande tous les 10 000 en même temps de manière asynchrone car je ne reçois que 500 réponses correctes.

Un peu de code pseudo pour mettre en évidence le Intention. P>

for {
  respA <- WS.url(url1).get
  id <- respA.body.split(",")
  respB <- WS.url(url2 + id).get
} yield ...


1 commentaires

Je pense que vous devriez d'abord identifier où se trouve le problème. Y a-t-il quelque chose qui ne va pas avec ws en jeu ou y a-t-il quelque chose qui ne va pas avec le point final. Est le point final qui jetait des erreurs http à un moment donné?


4 Réponses :


-2
votes

Utilisez une piscine de fil. L'URL suivante décrit l'ensemble du mécanisme: http://msdn.microsoft.com/fr -US / Bibliothèque / MS973903.aspx


3 commentaires

J'utilise déjà un bassin de fil de 8 (un par noyau). Le «problème» ici est que le framework de jeu est non bloquant de manière asynchrone et peut gérer plusieurs demandes par fil.


Eh bien, vous pouvez ensuite utiliser des demandes de blocage avec un bassin de fil beaucoup plus grand (commencez par 20 comme base). Un certain nombre de fils égaux au nombre de cœurs disponibles maximisent les performances des tâches intensives de la CPU. Cependant, un nombre plus important de threads peut être utilisé pour bloquer des opérations telles que des demandes de service io ou Web.


C'est certainement une option, mais vous perdriez alors tous les avantages sur ASYNC IO. Pourquoi ne pas éviter un grand nombre de fils de hoggage de mémoire inutile lorsque cela est possible.



7
votes

Vous devez faire une sorte de logement.

AKKA

Que diriez-vous d'utiliser des acteurs AKKA pour faire les demandes? Découvrez ces approches pour étrangler avec AKKA:

  • avoir un certain nombre d'enfants acteur S égal à la quantité de demandes simultanées que vous souhaitez faire. Chaque acteur enfant envoie une réponse au parent acteur à la fin de la demande HTTP. Chaque fois qu'un enfant acteur répond, envoyez-lui la prochaine demande de fabrication.
  • Utilisez TimerBasedthrottler pour goutter des messages d'alimentation à l'enfant acteur S qui rend les demandes HTTP: http://doc.akka.io/docs/akka/2.1.2/contrib/throttle.html
  • https://stackoverflow.com/a/9615080/936869

    juste avec des contrats à terme

    Si vous voulez simplement utiliser futur s et no akka acteur s, vous pouvez utiliser une combinaison de platmap (pour chaîner la chaîne http Les demandes d'arriver l'une après l'autre) et Future.Suence Pour obtenir le niveau de parallélisme que vous souhaitez.


0 commentaires

0
votes

Vous pouvez envisager de combiner les appels dans le deuxième service Web et ne passer que de passer à des lots ultérieurs après la fin du lot précédent. Cette approche pourrait ressembler à ceci:

val futs = batch.map(id => WS.url(url2 + id).get).toList


0 commentaires

10
votes

Voici un exemple d'application qui lotte 10 000 demandes (via la bibliothèque WS de la lecture) dans des groupes de 1 000 - tous de manière asynchrone et non bloquante: xxx


0 commentaires