Question

Je développe une application qui font des demandes au WebService Musicbrainz. Je lis dans le manuel MusicBrainz de ne pas faire plus d'une demande par seconde au WebService ou le client IP sera bloqué.

Quelle architecture proposez-vous afin de rendre cette restriction transparente au client de service.

  • Je voudrais appeler une méthode (getAlbuns par exemple) et il ne doit faire la demande de 1sec après la dernière demande.
  • Je veux aussi appeler 10 demande à la fois et le service doit gérer la mise en attente, le retour des résultats lorsque avaiable (non-blocage).

Merci!

Était-ce utile?

La solution

En raison du délai nécessaire entre les invocations, je vous suggère un java.util.Timer ou java.util.concurrent.ScheduledThreadPoolExecutor . Timer est très simple et parfaitement approprié pour cette utilisation cas. Mais si les exigences de planification supplémentaires sont identifiés plus tard, un seul Executor pouvait gérer tous. Dans les deux cas, utiliser la méthode de temporisation fixe, et non pas un procédé à taux fixe.

La tâche récurrente blocage sur la file d'attente jusqu'à ce qu'une demande est reçue, alors le temps d'enregistrement. Après traitement de la demande, le temps est à nouveau vérifié. Si la différence de temps est moins d'une seconde, sommeil pour le reste. Cette configuration suppose que le délai d'une seconde est nécessaire entre le début d'une demande et la suivante. Si le retard est nécessaire entre la fin d'une demande et la prochaine, vous ne avez pas besoin de vérifier le temps; juste dormir pendant une seconde.

Une autre chose à noter est que le service pourrait être en mesure d'accepter plusieurs requêtes en une seule demande, ce qui réduirait les frais généraux. Dans le cas contraire, profiter de ce en bloquant sur take() pour le premier élément, puis en utilisant poll() , peut-être avec un temps de blocage très court (5 ms environ), pour voir si l'application fait d'autres demandes. Dans ce cas, ceux-ci peuvent être regroupés en une seule requête au service. Si queue est un BlockingQueue<? extends Request>, il pourrait ressembler à ceci:

    Collection<Request> bundle = new ArrayList<Request>();
    bundle.add(queue.take());
    while (bundle.size() < BUNDLE_MAX) {
      Request req = queue.poll(EXTRA, TimeUnit.MILLISECONDS);
      if (req == null)
        break;
      bundle.add(req);
    }
    /* Now make one service request with contents of "bundle". */

Autres conseils

Vous devez définir un "service proxy" local que vos clients locaux appelleront.

Le proxy local recevra les demandes et le transmettre au service réel. Mais seulement à raison d'un message par seconde.

Comment vous faites cela dépend beaucoup de la tecnoligy à votre disposition.

Le plus simple serait un service java mutithreaded avec une statique et synchronisée LastRequestTime à long;.. » Variable d'horodatage (Bien que vous auriez besoin des acrobaties de code pour garder vos demandes dans l'ordre)

Un service plus sophistiqué pourrait avoir des fils de travailleurs recevant les demandes et les placer sur une file d'attente avec un seul fil ramassant les demandes et de les transmettre au service réel.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top