Frage

Ich habe immer noch Probleme mit der Spring-Integration – hier ist mein Szenario:

  1. Ein Webdienst erhält eine Anfrage von Client A
  2. Der Webdienst stellt die Anfrage in eine Warteschlange
  3. Ein Warteschlangenkonsument verarbeitet das Nachrichten-FIFO und sendet eine Antwort, die an den Webdienst zurückgeleitet wird
  4. Webdienste senden eine Antwort an Client A zurück

Es wird mehrere Webdienste geben, die alle Nachrichten in diese Warteschlange einspeisen, und ich muss sicherstellen, dass sie wirklich in der Reihenfolge verarbeitet werden, in der sie empfangen werden.

Welche Teile der Spring-Integration muss ich miteinander verbinden?

War es hilfreich?

Lösung

Ich kann Ihnen bei der Frühlingsintegration nicht helfen, aber vielleicht müssen Sie Ihrer Architektur einen zweiten Gedanken machen. In ESB -Systemen legen Sie normalerweise eine Nachricht in eine Warteschlange ein, wenn Sie wissen, dass die Verarbeitung der Nachricht viel Zeit in Anspruch nimmt oder wenn Sie nicht sicher sind, dass das Remote -Ende fertig ist (ein weiterer Grund ist, inkompatible Komponenten zu überbrücken). Wenn Sie die Nachricht zur Warteschlange hinzufügen, kehren Sie sofort zu dem Antragsteller zurück, der angibt, dass die Nachricht empfangen wird, aber nicht das Ergebnis der Operation bereitstellt. Der Antragsteller müsste dann für das Ergebnis befragt oder Sie können alternativ eine Art "Push" -Funktionalität bereitstellen.

Wenn die Verarbeitung der Nachrichten in der Warteschlange viel Zeit in Anspruch nimmt, empfehle ich, Ihre Architektur zu ändern. Es ist nicht üblich, dass ein Web -Client lange auf die Antwort wartet, und viele Anfragen könnten ebenfalls ein Zeitüberschreiten.

Wenn andererseits die Verarbeitung der Nachrichten schnell und zuverlässig ist, ist die Verwendung von Warteschlangenkanälen nicht erforderlich. Lassen Sie alle Ihre Nachrichten mit einer zentralen Komponente (Java ee Session Bean, Spring Bean, Web Service) kommunizieren und implementieren Sie selbst einen Warteschlangenmechanismus. Es handelt sich bereits um Antworten, die darüber abdecken, wie Sie dies tun könnten.

Andere Tipps

Basierend auf dem Javadoc für QueueChannel Hier ist mein Versuch dazu.Dies betrifft nicht die Webdienstkonfiguration, sondern nur den Code, der in die Back-End-Implementierung des Webdiensts einfließen würde.

Dies ist der Code, der einer Warteschlange (Ihrem Webdienst) etwas hinzufügen würde.

public class TheWebService {

  // Could also use QueueChannel, or PollableChannel here instead
  // just picked the most general one
  private org.springframework.integration.channel.MessageChannel queue;

  public void yourWebServiceMethod(SomeArg arg) {
     SomeObjectToPassThatExtendsMessage passed = someInitialProcessing(arg);
     queue.send(passed);
  }
}

Dies ist der Code, der in Ihre Receiver-/Prozessor-/Dequeue-Klasse eingefügt werden würde

public class TheProcessor {

  // Could also use QueueChannel here instead
  // just picked the most general one
  private org.springframework.integration.channel.PollableChannel queue;

  // This method needs to be setup to be called by a separate thread.
  // See http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/scheduling/package-summary.html
  // and it's sub-packages.
  public void someProcessingPoller() {
     SomeObjectToPassThatExtendsMessage passed = queue.receive();
     // Do some processing with the passed object.
  }

}

Die Spring-Konfiguration dafür würde in etwa so aussehen

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans">

  <bean id="webService" class="mypackage.TheWebService">
      <property name="queue" ref="queue" />
  </bean>

  <bean id="processor" class="mypackage.TheProcessor ">
      <property name="queue" ref="queue" />
  </bean>

  <bean id="queue" class="org.springframework.integration.channel.QueueChannel"/>
</beans>

Beachten Sie sicher, dass Java 5 eine Reihe von Blockingqueueus mit FIFO verarbeiten kann.

Sie sollten sich entweder die HTTP (für Ruhe) oder WS (für Pocken/Seife) "Inbound-Gateway" -Elemente in der Frühlingsintegration ansehen. Beide können über das Attribut "Request-Channel" mit einem gemeinsam genutzten Kanal "Request-Channel" angeschlossen werden (das Routing einer Antwort durch das gleiche Gateway kann hinter den Kulissen behandelt werden). Ich würde empfehlen, mit dem Durchsuchen der Proben zu beginnen. Dieser Blog sollte Ihnen helfen, aufzustehen: Laufen: http://blog.springource.com/2010/09/29/new-Spring-integration-amples/

Ich hoffe, das hilft. -Markieren

Das Problem ist nicht auf dem Frühling. Ich denke, Sie benötigen eine Warteschlange mit Elementen, die die Anfrage enthalten und eine Antwort anbieten. Die Antwort muss jedoch blockieren, bis das Element dequer und verarbeitet ist. Das Warteschlangenelement sieht also aus wie:

public class BlockingPair {
  private final RequestBodyType request;
  private ResponseBodyType response;

  public BlockingPair(RequestBodyType request) {
    this.request = request;
  }

  public RequestBodyType getRequest() {
    return request;
  }

  public ResponseBodyType getResponse() {
    while (response == null) {
      Thread.currentThread().sleep(10);
    }
    return response;
  }

  public void setResponse(ResponseBodyType response) {
    this.response = response;
  }
}

Das WebService Enqueing erstellt das BlockingPair mit seiner Anfrage. Drücken Sie das BlockingPair -Element in die Warteschlange. Danach schafft es die Reaktion, die den Reaktionskörper aus dem BlockingPair bekommt, aber Blöcke.

Der Verbraucher deques One BlockingPair und setzt den Reaktionskörper. Von dort aus schreibt der WebService die Antwort weiter.

Sie benötigen drei Bohnen: WebService, eine blockierende Warteschlange und der Verbraucher. Sowohl WebService als auch Verbraucher benötigen die Warteschlange als Bean -Eigenschaft.

Die Warteschlange und die Verbraucherbohnen müssen im Anwendungskontext geplant werden (wie initilialisiert von der ContextLoaderListener). Die Warteschlange benötigt eine Bean -ID, um nach dem Webservice Referenzen zu sein (der einen eigenen Kontext hat, aber der Anwendungskontext als übergeordnetes Übergeordneter, damit die Warteschlangereferenz verwiesen werden kann):

Teil von web.xml:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
  <servlet-name>service</servlet-name>
  <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>service</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

Das applicationContext.xml Enthält zwei Bohnen:

<bean id="queue" class="java.util.concurrent.LinkedBlockingQueue"/>

<bean id="consumer" class="...">
  <property name="queue" ref="queue"/>
</bean>

Der Webservice hat hier seine eigene Kontextdefinition service-servlet.xml:

<bean id="endpoint" class="org.springframework.ws.server.endpoint....PayloadEndpoint">
  <property name="queue" ref="queue"/>
</bean>

Weitere Informationen zum Definieren eines Frühlings -WS -Endpunkts finden Sie in der Frühlings -Tutorial.

Der Verbraucher muss eine Hintergrundaufgabe sein, also würde ich es vorziehen Quarz, für die Frühlingsintegration siehe hier.

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