首页 文章

Spring集成:将Web服务挂钩到FIFO队列

提问于
浏览
2

我仍在努力使用Spring Integration-这是我的方案:

  • Web服务从客户端A获取请求

  • Web服务将请求放入队列

  • 队列使用者处理消息FIFO并发送一个响应,该响应被路由回Web服务

  • Web服务将响应发送回客户端A.

将有多个Web服务将消息传送到此队列,我需要确保它们按照接收的顺序进行真正的处理 .

我需要将哪些Spring Integration连接在一起?

5 回答

  • 0

    我无法帮助您使用Spring Integration,但也许您需要再次考虑您的架构 . 在ESB系统中,当您知道消息的处理将花费相当长的时间或者您不确定远程端是否准备就绪时,您通常会在队列中放置消息(另一个原因是桥接不兼容的组件) . 将消息添加到队列时,会立即返回到请求者,指示已收到消息,但未提供操作结果 . 然后请求者需要轮询结果,或者您可以选择提供某种“推送”功能 .

    因此,如果处理队列中的消息需要花费大量时间,我建议您修改架构 . Web客户端长时间等待回复并不常见,许多请求也可能超时 .

    另一方面,如果消息的处理快速可靠,则不需要使用队列信道 . 让所有消息与中央组件(Java EE会话Bean,Spring Bean,Web服务)通信,并自己实现队列机制 . 他们已经回答了如何做到这一点 .

  • 1

    基于Javadoc的QueueChannel这是我的尝试 . 这不涉及Web服务配置,只涉及Web服务后端实现中的代码 .

    这是将某些内容添加到队列(您的Web服务)的代码 .

    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);
      }
    }
    

    这是您的接收器/处理器/出队类中的代码

    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.
      }
    
    }
    

    Spring的配置看起来像

    <?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>
    
  • 2

    请注意Spring Integration,但Java 5有许多可以处理FIFO的BlockingQueues .

  • 7

    您应该在Spring Integration中查看http(用于REST)或ws(用于POX / SOAP)"inbound-gateway"元素 . 任何一个都可以通过"request-channel"属性连接到共享的队列支持的通道(通过同一网关的回复路由可以在后台处理) . 我建议首先浏览样本 . 此博客应该可以帮助您启动并运行:http://blog.springsource.com/2010/09/29/new-spring-integration-samples/

    希望有所帮助 . -标记

  • 1

    问题不是 Spring 天 . 我想你需要一个包含请求的元素的队列并提供响应 . 但是响应需要阻止,直到元素被去除并处理 . 所以队列元素看起来像:

    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;
      }
    }
    

    webservice enqueing使用其请求主体创建BlockingPair . 比将BlockingPair元素推送到队列 . 然后它创建响应从BlockingPair获取响应主体,但阻止 .

    消费者欺骗一个BlockingPair并设置响应主体 . 从那里,webservice继续编写响应 .

    您需要三个bean:webservice,阻塞队列和使用者 . webservice和consumer都需要将队列作为bean属性 .

    需要在应用程序上下文中规划队列和使用者bean(由 ContextLoaderListener 初始化) . 队列需要一个bean id作为webservice的引用(它有自己的上下文,但是应用程序上下文作为父项,因此可以引用队列引用):

    部分 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>
    

    applicationContext.xml 包含两个bean:

    <bean id="queue" class="java.util.concurrent.LinkedBlockingQueue"/>
    
    <bean id="consumer" class="...">
      <property name="queue" ref="queue"/>
    </bean>
    

    webservice有自己的上下文定义,这里 service-servlet.xml

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

    有关定义spring ws endpoints 的更多信息,请参阅spring tutorial .

    消费者需要成为后台任务,所以我更喜欢quartz,对于 Spring 季整合,请参见here .

相关问题