2010-06-10 5 views
5

Para el siguiente escenario estoy en busca de sus consejos y sugerencias sobre las mejores prácticas:¿Cómo aprovechar Spring Integration en una arquitectura distribuida JMS del mundo real?

En un sistema distribuido (principalmente basado en Java) con:

  • muchos (diferentes) aplicaciones cliente (web-app Herramientas de línea de comandos REST API)
  • un agente de mensajes JMS central (actualmente a favor del uso de ActiveMQ)
  • nodos de procesamiento independientes múltiples (que se ejecutan en varias máquinas remotas, calculan costosas operaciones de diferentes tipos según lo especificado por la carga útil del mensaje JMS)

¿Cómo se puede aplicar mejor el soporte JMS proporcionado por el marco Spring Integration para desacoplar los clientes de los nodos de trabajador? Al leer la documentación de referencia y algunos primeros experimentos, parece que la configuración de un adaptador de entrada JMS requiere intrínsecamente el uso de un suscriptor, que en un escenario desacoplado no existe.

Nota pequeña: la comunicación debe realizarse a través de mensajes de texto JMS (utilizando una estructura de datos JSON para futuras ampliaciones).

Respuesta

4

Esto realmente no responde a su pregunta, pero asegúrese de consultar Apache Camel para conectar sus diferentes componentes. Lo encontré extremadamente útil para conectar una cola JMS a un servicio web existente y planeo usarlo también para otros componentes.

Un ejemplo que supervisa una cola de ActiveMQ para los mensajes, las transforma y las publicará a un servicio web:

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:camel="http://camel.apache.org/schema/spring" 
    xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
     http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring-2.3.0.xsd"> 

<bean id="callbackProcessor" class="com.package.CallbackProcessor"/> 

<bean id="activemq" class="org.apache.camel.component.jms.JmsComponent"> 
    <property name="connectionFactory" ref="jmsFactory" /> 
</bean> 

<camel:camelContext id="camel"> 
    <!-- Must put this in camel:endpoint because camel:from doesn't support property substitution --> 
    <camel:endpoint id="callbackQueue" uri="activemq:queue:${jms.callback-queue-name}"/> 
    <camel:route> 
     <camel:from ref="callbackQueue"/> 
     <camel:process ref="callbackProcessor"/> 
     <camel:to uri="http://dummy"/><!-- This will be replaced by the callbackProcessor with the callback URL in the message --> 
    </camel:route> 
</camel:camelContext> 
</beans> 

Eso es todo lo que es necesario en nuestra solicitud de primavera para encender camello y comenzar a procesar los mensajes.

+0

Gracias, Camel es, por supuesto, también una opción, pero ¿no requeriría más sobrecarga de configuración o es factible? – ngeek

+0

No creo que sea demasiada configuración. He actualizado mi respuesta con un ejemplo. –

+0

Cierto, esto se ve de hecho muy conciso. Gracias por publicar más detalles. – ngeek

1

¿Está preguntando si Spring Integration se puede utilizar para implementar un protocolo bridge? Entonces la respuesta es sí, y lo hace simplemente.

+0

No estoy seguro de que esto solucione mi situación: por un lado, una aplicación cliente se configuraría para usar un adaptador de canal entrante para entregar los mensajes en la cola JMS, y en un nodo de procesamiento se configuraría para usar un correo saliente adaptador para recogerlo y procesarlo. – ngeek

+0

Supuse que quería desacoplar los protocolos. Las aplicaciones del cliente se mantendrían casi sin cambios, excepto para comunicarse con una aplicación de puente con su protocolo de elección WS, REST, etc.La aplicación de puente convertiría todas estas solicitudes en solicitudes JMS que sus nodos trabajadores consumirían en un patrón de consumidor competidor. –

+0

Eso es correcto en el caso óptimo de que el cliente no deba saber nada sobre el protocolo. ¿Podría explicar cómo hacer el mejor uso del patrón de puente en el escenario descrito? Gracias. – ngeek

3

Aquí está la integración de Spring que me esperaba hoy, si encuentra cosas que podrían mejorar, siga por favor.

En el lado del cliente los mensajes pueden ser enviados y recibidos a través de un SimpleMessagingGateway:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:integration="http://www.springframework.org/schema/integration" 
    xmlns:jms="http://www.springframework.org/schema/integration/jms" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context.xsd 
      http://www.springframework.org/schema/integration/jms 
      http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd 
      http://www.springframework.org/schema/integration 
      http://www.springframework.org/schema/integration/spring-integration.xsd"> 

    <import resource="integration-common.xml"/> 

    <!-- Communication Gateway for the Client (send/receive) --> 
    <bean id="gateway" class="org.springframework.integration.gateway.SimpleMessagingGateway"> 
     <property name="requestChannel" ref="SenderChannel"/> 
     <property name="replyChannel" ref="InboundChannel"/> 
     <property name="replyTimeout" value="1000"/> 
    </bean><!-- TODO: could use integration:gateway --> 

    <!-- Sending out message to JMS request queue --> 
    <integration:channel id="SenderChannel"/> 
    <jms:outbound-channel-adapter 
         channel="SenderChannel" 
         destination="requestQueue" /> 

    <!-- Listen to incoming messages on JMS reply queue --> 
    <integration:channel id="InboundChannel"> 
     <integration:queue/> 
    </integration:channel> 
    <jms:message-driven-channel-adapter 
      destination="replyQueue" 
      channel="InboundChannel" /> 

</beans> 

Y la configuración en el nodo de procesamiento del lado parece (véanse los comentarios en línea para una explicación más detallada de la integración de Primavera elementos):

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:integration="http://www.springframework.org/schema/integration" 
    xmlns:jms="http://www.springframework.org/schema/integration/jms" 
    xmlns:stream="http://www.springframework.org/schema/integration/stream" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context.xsd 
      http://www.springframework.org/schema/integration/jms 
      http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd 
      http://www.springframework.org/schema/integration 
      http://www.springframework.org/schema/integration/spring-integration.xsd"> 

    <import resource="integration-common.xml"/> 

    <!-- Read in Message Endpoint Service Activator classes --> 
    <context:component-scan base-package="sample.integration.jmsbasic"/> 

    <!-- Listen to incoming messages on the JMS request queue --> 
    <integration:channel id="jmsinToProcChannel"/> 
    <jms:message-driven-channel-adapter 
      destination="requestQueue" 
      channel="jmsinToProcChannel"/> 

    <!-- Delegate message to service implementation and take care of answer --> 
    <integration:service-activator 
      input-channel="jmsinToProcChannel" 
      ref="procService" 
      output-channel="jmsBackChannel" /> 

    <!-- Send answer back to JMS reply queue --> 
    <integration:channel id="jmsBackChannel"/> 
    <jms:outbound-channel-adapter 
         channel="jmsBackChannel" 
         destination="replyQueue" /> 

</beans> 
Cuestiones relacionadas