Frage

Ich fange an, ein Java EE-Projekt, dass der Bedarf stark skalierbar sein. Bisher war das Konzept:

  • mehr Message Driven Beans, verantwortlich für die verschiedenen Teile der Architektur
  • jede MDB hat eine Session Bean injiziert, die Business-Logik Handhabung
  • ein paar Entity Beans, die den Zugang auf die Persistenz-Schicht
  • Kommunikation zwischen den verschiedenen Teilen der Architektur über Request / Reply-Konzept über JMS-Nachrichten:
    • MDB empfängt msg enthält Aktivität Anfrage
    • nutzt seine Session-Bean notwendig Geschäftslogik auszuführen
    • liefert Antwortobjekt in msg ursprünglichen Anforderer

Die Idee war, dass durch Entkoppeln Teile der Architektur voneinander über den Message-Bus gibt es keine Begrenzung für die Skalierbarkeit ist. Einfach mehr Komponenten beginnen -., Solange sie mit dem gleichen Bus verbunden sind, können wir wachsen und wachsen

Leider sind mit wir massive Probleme mit der Anfrage-Antwort-Konzept. Transaktion Mgmt scheint in unserer Art und Weise viel zu sein. Es Nähte, die Session Beans sollen nicht Nachrichten konsumieren?!

Beim Lesen http://blogs.oracle.com/fkieviet/entry/request_reply_from_an_ejb und http://forums.sun.com/message.jspa?messageID=10338789 , ich habe das Gefühl, dass die Menschen em eigentlich empfehlen <> gegen die Anfrage / Antwort-Konzept für EJBs.

Wenn das der Fall ist, wie tun kommunizieren Sie zwischen Ihrem EJBs? (Denken Sie daran, Skalierbarkeit ist, was ich nach)

Details meiner aktuellen Setup:

  • MDB 1 'Testcontroller', Anwendungen (lokal) SLSB 1 'Testservice' für Business-Logik
  • TestController.onMessage () macht Testservice eine Nachricht senden XYZ in der Warteschlange und fordert eine Antwort
    • Testservice verwendet Bean Managed Transaktionen
    • Testservice stellt eine Verbindung & Sitzung mit dem JMS-Broker über eine gemeinsame Verbindung Fabrik bei der Initialisierung (@PostConstruct)
    • Testservice verpflichtet, die Transaktion nach dem Senden, dann beginnt eine weitere Transaktion und wartet 10 Sekunden für die Antwort
  • Meldung wird auf MDB 2 'LocationController', die Anwendungen (lokal) SLSB 2 'LocationService' für Business-Logik
  • LocationController.onMessage () macht LocationService eine Nachricht senden zurück , um die angeforderten JMSReplyTo Warteschlange
    • Samen BMT Konzept, gleiches @PostConstruct Konzept
  • verwenden alle die gleiche Verbindung Fabrik den Broker zugreifen

Problem: Die erste Nachricht senden wird (durch SLSB 1) und empfangen (von MDB 2) ok. Das Senden der Rückkehr-Nachricht (von SLSB 2) als auch in Ordnung. Allerdings SLSB 1 nie erhält etwas -. Es einfach mal aus

habe ich versucht, ohne den messageSelector, keine Veränderung, noch kein Empfang Nachricht.

Ist es nicht ok Nachricht von einem Session-Bean zu konsumieren?

SLSB 1 - TestService.java

@Resource(name = "jms/mvs.MVSControllerFactory")
private javax.jms.ConnectionFactory connectionFactory;

@PostConstruct
public void initialize() {
    try {
      jmsConnection = connectionFactory.createConnection();
      session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      System.out.println("Connection to JMS Provider established");
    } catch (Exception e) { }
}

public Serializable sendMessageWithResponse(Destination reqDest, Destination respDest, Serializable request) {
    Serializable response = null;

    try {
        utx.begin();
        Random rand = new Random();
        String correlationId = rand.nextLong() + "-" + (new Date()).getTime();

        // prepare the sending message object
        ObjectMessage reqMsg = session.createObjectMessage();
        reqMsg.setObject(request);
        reqMsg.setJMSReplyTo(respDest);
        reqMsg.setJMSCorrelationID(correlationId);

        // prepare the publishers and subscribers
        MessageProducer producer = session.createProducer(reqDest);

        // send the message
        producer.send(reqMsg);
        System.out.println("Request Message has been sent!");
        utx.commit();

        // need to start second transaction, otherwise the first msg never gets sent
        utx.begin();
        MessageConsumer consumer = session.createConsumer(respDest, "JMSCorrelationID = '" + correlationId + "'");
        jmsConnection.start();
        ObjectMessage respMsg = (ObjectMessage) consumer.receive(10000L);
        utx.commit();

        if (respMsg != null) {
            response = respMsg.getObject();
            System.out.println("Response Message has been received!");
        } else {
            // timeout waiting for response
            System.out.println("Timeout waiting for response!");
        }

    } catch (Exception e) { }

    return response;
}

SLSB 2 - LocationService.Java (nur die Antwort Methode, Rest ist wie oben)

public boolean reply(Message origMsg, Serializable o) {
    boolean rc = false;

    try {
        // check if we have necessary correlationID and replyTo destination
        if (!origMsg.getJMSCorrelationID().equals("") && (origMsg.getJMSReplyTo() != null)) {
            // prepare the payload
            utx.begin();
            ObjectMessage msg = session.createObjectMessage();
            msg.setObject(o);

            // make it a response
            msg.setJMSCorrelationID(origMsg.getJMSCorrelationID());
            Destination dest = origMsg.getJMSReplyTo();

            // send it
            MessageProducer producer = session.createProducer(dest);
            producer.send(msg);
            producer.close();
            System.out.println("Reply Message has been sent");
            utx.commit();

            rc = true;
        }

    } catch (Exception e) {}

    return rc;
}

Sonnen resources.xml

<admin-object-resource enabled="true" jndi-name="jms/mvs.LocationControllerRequest"  res-type="javax.jms.Queue"  res-adapter="jmsra">
    <property name="Name" value="mvs.LocationControllerRequestQueue"/>
</admin-object-resource>
<admin-object-resource enabled="true" jndi-name="jms/mvs.LocationControllerResponse"  res-type="javax.jms.Queue"  res-adapter="jmsra">
    <property name="Name" value="mvs.LocationControllerResponseQueue"/>
</admin-object-resource>

<connector-connection-pool name="jms/mvs.MVSControllerFactoryPool"  connection-definition-name="javax.jms.QueueConnectionFactory"  resource-adapter-name="jmsra"/>
<connector-resource enabled="true" jndi-name="jms/mvs.MVSControllerFactory" pool-name="jms/mvs.MVSControllerFactoryPool"  />
War es hilfreich?

Lösung

Die Anforderung / Antwort-Muster, auch wenn JMS verwenden, ist immer noch Synchron im Wesentlichen. Der Anrufer sendet eine Nachricht, und wartet dann auf die Antwort. Dies ist nicht nur kompliziert, weil die verteilten Transaktionen, sondern bedeutet auch, dass, während für die Antwort warten, einer oder mehrere Ressourcen (der Faden zumindest in diesem Fall) zugeordnet ist und verschwendet. Sie können nicht auf diese Weise skalieren. Sie von Natur aus durch die Anzahl der Threads beschränkt sind

Um ein wirklich skalierbare JMS Architektur alles sein muss asynchron . Mit anderen Begriff: Sie sollten nie warten. Die Nachricht gesendet und empfangen sollten die notwendigen Informationen zur Auslösung der nächsten Aktivität übergeben.

Wenn die Größe der Nachricht zu groß sein würde, können Sie speichern nur eine Kennung und speichert die entsprechenden Daten in einer Datenbank. Aber dann wird die Datenbank wieder ein Streitpunkt.

Wenn verschiedene Nachrichten, in denen wissen müssen lang andauernden Prozess, den sie teilnehmen, können Sie auch verwenden Korrelation Identifikatoren . Wenn eine Nachricht empfangen wird, empfangen kann die „Wiederaufnahme“ der Langlaufaktivität die Korrelationskennung verwendet wird. Das ist ein traditionelles Muster mit BPEL. Der Hauptunterschied zwischen synchroner Anforderung / Antwort und asynchroner Nachricht mit Korrelations-Kennung ist, dass die Ressourcen zwischen jedem Schritt freigesetzt werden können. Sie können mit der später skalieren, aber nicht mit dem ersten.

Um ehrlich zu sein, war ich mit dem langen Post verwirre und nicht verstanden, wenn Ihr Design eher asynchron ist (und richtig) oder synchron mit Anforderungs- / Antwort (und problematisch). Aber ich hoffe, dass ich zur Verfügung gestellt ein Element der Antwort.

Auf jeden Fall die Website gehen unter Enterprise Integration Patterns , es ist eine wertvolle Quelle für Information.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top