Ist es eine gute Vorgehensweise, JMS Temporary Queue für synchrone Verwendung zu verwenden?
Wenn wir die JMS-Anfrage/Antwort-Mechanismus verwenden "Temporäre Queue" wird, dass code skalierbar sein?
Als jetzt, wir wissen nicht, ob wir Unterstützung von 100 requests pro Sekunde oder 1000 Anfragen pro Sekunde.
Den code unten ist was ich denke bin von der Umsetzung. Es macht den Einsatz von JMS in einer 'Synchronen' Mode. Die wichtigsten Teile sind, wo der "Verbraucher" wird erstellt, um Punkt a 'Temporäre Queue' , wurde für diese Sitzung. Ich kann nicht einfach herauszufinden, ob die Verwendung solcher Temporären Warteschlangen ist ein skalierbares design.
destination = session.createQueue("queue:///Q1");
producer = session.createProducer(destination);
tempDestination = session.createTemporaryQueue();
consumer = session.createConsumer(tempDestination);
long uniqueNumber = System.currentTimeMillis() % 1000;
TextMessage message = session
.createTextMessage("SimpleRequestor: Your lucky number today is " + uniqueNumber);
//Set the JMSReplyTo
message.setJMSReplyTo(tempDestination);
//Start the connection
connection.start();
//And, send the request
producer.send(message);
System.out.println("Sent message:\n" + message);
//Now, receive the reply
Message receivedMessage = consumer.receive(15000); //in ms or 15 seconds
System.out.println("\nReceived message:\n" + receivedMessage);
Update:
Stieß ich auf ein anderes Muster, siehe dieser blog
Die Idee ist die Verwendung von "normaler" Warteschlangen für das Senden und Empfangen. Aber für 'Synchronen' Anrufe, um die gewünschte Reaktion (z.B. übereinstimmung der Anfrage), erstellen Sie ein Verbraucher, der hört die Receive queue mit einem "Selektor".
Schritte:
//1. Create Send and Receive Queue.
//2. Create a msg with a specific ID
final String correlationId = UUID.randomUUID().toString();
final TextMessage textMessage = session.createTextMessage( msg );
textMessage.setJMSCorrelationID( correlationId );
//3. Start a consumer that receives using a 'Selector'.
consumer = session.createConsumer( replyQueue, "JMSCorrelationID = '" + correlationId + "'" );
So ist der Unterschied in diesem Muster ist, dass wir nicht erstellen Sie einen neuen temp-Warteschlange für jede neue Anfrage.
Stattdessen werden alle Antworten, die kommen, um nur eine queue, aber mit einem "Schalter" um sicherzustellen, dass jede Anfrage-thread erhält nur die Antwort, die ist kümmert.
Ich denke der Nachteil hier ist, dass Sie einen "Selektor". Ich weiß noch nicht, ob das ist weniger bevorzugt oder bevorzugt man mehr als die zuvor erwähnten Muster. Gedanken?
InformationsquelleAutor der Frage rk2010 | 2012-05-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bezüglich der Updates in Ihrer post - Selektoren sind sehr effizient, wenn durchgeführt, auf die Kopfzeilen der Nachricht, wie Sie mit der Korrelations-ID. Spring Integration auch intern bedeutet dies für die Implementierung eines JMS-Outbound-gateway.
InformationsquelleAutor der Antwort Biju Kunjummen
Interessant, die Skalierbarkeit dieser kann tatsächlich das Gegenteil von dem, was die anderen Antworten beschrieben habe.
WebSphere MQ speichert und wiederverwendet, dynamische queue-Objekten wo dies möglich ist. So, obwohl die Verwendung einer dynamischen Warteschlange ist nicht frei, es wird gut skalieren, weil wie die Schlangen sind befreit, alle, dass ein Fehler in WMQ Bedürfnisse zu tun ist, übergeben Sie den Griff, bis der nächste thread, fordert eine neue queue-Instanz. In einer belebten QMgr, die Anzahl der dynamischen Warteschlangen bleiben relativ statisch, während die Griffe weitergeleitet von thread zu thread. Streng genommen ist es nicht ganz so schnell, wie die Wiederverwendung einer einzelnen Warteschlange, aber es ist nicht schlecht.
Auf der anderen Seite, obwohl die Indizierung auf
CORRELID
ist schnell, Leistung ist invers zu der Anzahl der Nachrichten im index. Es macht auch einen Unterschied, wenn die queue-Tiefe beginnt zu bauen. Wenn die app geht einGET
mitWAIT
auf eine leere Warteschlange, gibt es keine Verzögerung. Aber auf eine Tiefe Warteschlange, die QMgr suchen muss, der index der vorhandenen Nachrichten, um festzustellen, dass die Antwort-Nachricht ist nicht unter Ihnen. In deinem Beispiel ist der Unterschied zwischen der Suche eine leere index im Vergleich zu einem großen index 1,000 s von mal pro Sekunde.Das Ergebnis ist, dass 1000 dynamische Warteschlangen mit einer Nachricht kann sich jeder wirklich schneller als eine einzelne Warteschlange mit 1000 threads immer von
CORRELID
je nach den Eigenschaften der app und der Last. Ich würde empfehlen dieses zu testen, die skaliert, bevor Begehen zu einem bestimmten design.InformationsquelleAutor der Antwort T.Rob
Mittels Wahlschalter auf Korrelations-ID auf eine freigegebene Warteschlange skaliert sehr gut mit mehreren Verbrauchern.
1000 requests /s, wird jedoch eine Menge. Sie möchten vielleicht teilen Sie den laden ein bisschen zwischen den verschiedenen Instanzen, wenn die Leistung stellt sich heraus, ein problem zu sein.
Möchten Sie vielleicht zu erarbeiten, die den Anforderungen der vs-Kunden zahlen. Wenn die Anzahl der clients < 10 und bleibt eher statisch, und die Anfrage zahlen sind sehr hoch, die am meisten belastbar und schnelle Lösung könnte sein, die haben statische Antwort der Warteschlangen für jeden client.
InformationsquelleAutor der Antwort Petter Nordlander
Erstellen von temporären Warteschlangen ist nicht frei. Schließlich ist die Zuteilung der Ressourcen auf der broker(s). Having said, die, wenn Sie einen unbekannten (vor der hand) potentiell ungebundene Anzahl von clients (mehrere JVMs, die mehrere gleichzeitige threads pro JVM, etc) Sie dürfen keine Wahl haben. Pro-Zuweisung von client-Warteschlangen und Zuordnung zu Kunden würden aus der hand fallen.
Sicherlich, was haben Sie skizziert, ist die einfachste mögliche Lösung. Und wenn man real-zahlen für Umsatz und Skalen genug, fein.
Bevor ich Aussehen würde, zu verhindern, dass temporäre queues, ich würde schauen mehr auf die Begrenzung der Anzahl der Kunden und den Kunden lange gelebt. Das ist zu sagen, erstellen Sie eine client-pool auf der client-Seite, und haben Sie die Kunden in den pool erstellen der temporären queue, session, Verbindung, etc. beim Start Wiederverwendung bei nachfolgenden Anfragen und Riss diese dann auf Herunterfahren. Dann das tuning-problem zu einem der min/max-Größe auf den pool, was die idle-time zu beschneiden, den pool und das Verhalten (fail vs block), wenn der pool ausgeschöpft ist. Es sei denn, Sie erstellen eine beliebig große Anzahl von Transienten JVMs (in dem Fall haben Sie größere Skalierung Probleme, die nur von der JVM startup-overhead), sollte das doch so gut skalieren wie alles andere. Nach allem, an diesem Punkt die Ressourcen, die Sie zuweisen der tatsächlichen Nutzung des Systems. Gibt es wirklich keine Möglichkeit, weniger als das.
Ist die Sache zu vermeiden, ist die Schaffung und die Zerstörung eines großen unentgeltliche Anzahl der Warteschlangen, sessions, verbindungen, etc. Design der server-Seite ermöglichen das streaming von der get-go. Dann Lache wenn/Wann Sie es benötigen. Wie nicht, für alles, was nicht-trivial, Sie müssen.
InformationsquelleAutor der Antwort asudell
Temporäre queue kostet die Erstellung relyToProducers jeder zu jeder Zeit. Anstelle der Verwendung eines Cache-Produzenten für eine statische replyToQueue, die Methode createProducer teurer sind und Auswirkungen auf die Leistung in einem stark konkurrierenden Aufruf Umwelt.
InformationsquelleAutor der Antwort davy_wei
Habe ich vor dem gleichen problem und entschied, pool-verbindungen selbst innerhalb einer stateless bean. Einer client-Verbindung hat eine tempQueue und im inneren sieht JMSMessageExchanger-Objekt (enthält connectionFactory -, Queue-und tempQueue), die Bindung an eine bean-Instanz. Ich habe es getestet in JSE/EE-Umgebungen. Aber ich bin nicht wirklich sicher über Glassfish JMS-pool Verhalten.
Wird es eigentlich nahe JMS-verbindungen, erhalten "von hand" nach-bean-Methode beendet?Mache ich etwas furchtbar falsch???
Auch Ive deaktiviert Transaktion im client-bean (TransactionAttributeType.NOT_SUPPORTED) auf Anfrage senden Nachrichten sofort in der Warteschlange.
Gleichen Klasse wird verwendet, um client (stateless bean) und server (@MessageDriven).
RequestProducer und ResponseProducer Schnittstellen:
Zudem habe ich gelesen AMQ Artikel über Anfrage-Antwort-Implementierung über AMQ:
http://activemq.apache.org/how-should-i-implement-request-response-with-jms.html
InformationsquelleAutor der Antwort arbocdi
Vielleicht bin ich zu spät, aber ich verbrachte einige Stunden in dieser Woche zu bekommen-sync-Request/Reply-Arbeit in der JMS. Was über die Verlängerung der QueueRequester mit timeout. Ich habe und zumindest testen auf einer Maschine (läuft broker, requestor und replyer) zeigte, dass diese Lösung gegenüber den diskutierten lieben. Auf der anderen Seite hängt es mit einer QueueConnection und das bedeutet, dass Sie möglicherweise gezwungen werden, um mehrere Verbindungen öffnen.
InformationsquelleAutor der Antwort SteKreg