Requête-réponse synchrone simultanée avec JMS / ActiveMQ-Patterns / Libraries?

j'ai une application web où lorsque l'utilisateur soumet une demande, nous envoyons un message JMS à un service distant et attendons la réponse. (Il y a aussi des requêtes async, et nous avons divers subtilités configurées pour la rediffusion de messages, etc, Donc nous préférerions nous en tenir à JMS au lieu de, disons, HTTP)

dans comment mettre en œuvre la réponse à une demande avec JMS? , ActiveMQ semble décourager l'idée de files d'attente temporaires par demande ou les consommateurs temporaires avec des sélecteurs sur le JMSCorrelationID, en raison de la charge impliquée dans leur rotation.

cependant, si j'utilise des consommateurs groupés pour les réponses, Comment puis-je expédier du consommateur de réponse de nouveau au fil original de demande?

je pourrais certainement écrire mon propre thread-safe callback-registration/dispatch, mais je déteste écrire du code que je soupçonne a déjà été écrit par quelqu'un qui sait mieux que moi.

Qui ActiveMQ page recommande Lingo , qui n'a pas été mis à jour depuis 2006, et Camel Spring Remoting , qui a été banni par mon équipe pour ses nombreux bogues gotcha.

Existe-t-il une meilleure solution, sous la forme d'une bibliothèque mettant en œuvre Ce modèle, ou sous la forme d'un modèle différent pour simuler une requête-réponse synchrone sur JMS?


SI question:

23
demandé sur Community 2012-08-01 12:11:07

5 réponses

dans un projet antérieur, nous avons eu une situation similaire, où une demande de synchronisation a été traitée avec une paire de Messages JMS async req/res. Nous utilisions le JBoss JMS impl à l'époque et le destinations temporaire où un grand overhead.

nous avons fini par écrire un répartiteur sans fil, laissant le WS en attente jusqu'à la réponse du JMS. Nous avons utilisé le Corrélationid pour faire correspondre la réponse à la demande.

Cette solution était toute maison, mais Je suis tombé sur une belle carte de blocage impl qui résout le problème de faire correspondre une réponse à une demande.

BlockingMap

si votre solution est regroupée, vous devez prendre soin que les messages de réponse soient envoyés au noeud droit dans le cluster. Je ne sais pas ActiveMQ, mais je me souviens que JBoss messaging a quelques problèmes sous le capot pour leurs destinations groupables.

4
répondu maasg 2012-08-01 10:21:34

je pensais encore à L'utilisation de chameau et de le laisser gérer le filetage, peut-être sans printemps remoting, mais juste les temps de production brute.

Camel a une belle documentation sur le sujet et fonctionne très bien avec ActiveMQ. http://camel.apache.org/jms#JMS-RequestreplyoverJMS

pour votre question au sujet de la rotation d'un consommateur basé sur le sélecteur et les frais généraux, ce que le Docs ActiveMQ déclare réellement est qu'il nécessite un aller-retour vers le courtier ActiveMQ, qui pourrait se trouver de l'autre côté du globe ou sur un réseau à haut délai. Les frais généraux dans ce cas sont le temps aller-retour TCP/IP vers le courtier AMQ. Je ne considère pas cela comme une option. L'ont utilisé multiples reprises avec succès.

4
répondu Petter Nordlander 2012-08-01 20:03:54

un collègue a suggéré une solution potentielle-- une file d'attente de réponse/consommateur par thread webapp, et nous pouvons définir l'adresse de retour à la file d'attente de réponse détenue par ce thread particulier. Puisque ces threads sont typiquement de longue durée (et sont réutilisés pour des requêtes web subséquentes), nous n'avons qu'à subir la surcharge au moment où le thread est généré par le pool.

cela dit, tout cet exercice me fait repenser JMS vs HTTP... :)

3
répondu joshwa 2012-08-03 01:33:51

j'ai toujours utilisé CorrelationID pour la demande / réponse et je n'ai jamais eu de problèmes de performance. Je ne peux pas imaginer pourquoi ce serait un problème de performance du tout, il devrait être super rapide pour n'importe quel système de messagerie à mettre en œuvre et tout à fait une fonctionnalité importante à mettre en œuvre bien.

http://www.eaipatterns.com/RequestReplyJmsExample.html a les principales solutions de flux en utilisant replyToQueue ou correlationID.

0
répondu ams 2012-08-01 08:45:09

c'est un vieux, mais j'ai atterri ici à la recherche de quelque chose d'autre et en fait ont quelques idées (espérons qu'il sera utile à quelqu'un).

nous avons mis en place un cas d'utilisation très similaire avec Hazelcast étant notre châssis pour comminication de l'internode de cluster. L'essense est constituée de 2 ensembles de données: 1 carte distribuée pour les réponses, 1 liste "locale" d'awaiters de réponse (sur chaque noeud de la grappe).

  • chaque requête thread from Jetty) crée une entrée dans la carte des awaiters locaux; l'entrée a évidemment la corrélation UID et un objet qui servira de sémaphore
  • puis la requête est envoyée à la télécommande (REST / JMS) et le thread d'origine commence à attendre sur le sémaphore; UID doit faire partie de la requête
  • remote renvoie la réponse et l'écrit dans la carte des réponses avec L'UID corrélé
  • La carte des réponses
  • est en cours écoutée; si L'UID de la nouvelle réponse se trouve dans la carte des awaiters locaux, son sémaphore est notifié, le fil de la demande originale est libéré, récupérant la réponse de la carte des réponses et la retournant au client

il s'agit d'une description générale, je peux mettre à jour une réponse avec quelques optimisations que nous avons, au cas où il y aura un intérêt.

0
répondu GullerYA 2017-08-11 07:22:53