3

我仍在为 Spring 集成而苦苦挣扎——这是我的场景:

  1. Web 服务从客户端 A 获取请求
  2. Web 服务将请求放入队列
  3. 队列消费者处理消息 FIFO 并发送一个响应,该响应被路由回 Web 服务
  4. Web 服务将响应发送回客户端 A

将有多个 Web 服务都将消息提供到此队列中,我需要确保它们真正按照接收顺序进行处理。

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

4

5 回答 5

8

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

所以,如果处理队列中的消息需要很多时间,我建议修改你的架构。Web 客户端等待回复的时间很长并不常见,而且许多请求也可能超时。

另一方面,如果消息的处理快速可靠,则不需要使用队列通道。让您的所有消息都与一个中心组件(Java EE 会话 Bean、Spring Bean、Web 服务)进行通信,并自己实现一个队列机制。它们已经是涵盖如何做到这一点的答案。

于 2009-04-30T06:46:38.443 回答
2

基于QueueChannel的 Javadoc,这是我的尝试。这不涉及 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>
于 2009-04-29T21:23:22.603 回答
1

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

于 2009-04-25T18:08:14.213 回答
1

您应该查看 Spring Integration 中的 http(用于 REST)或 ws(用于 POX/SOAP)“inbound-gateway”元素。任何一个都可以通过“请求通道”属性连接到一个共享的、队列支持的通道(可以在后台处理通过同一网关返回的回复路由)。我建议从浏览示例开始。该博客应该可以帮助您启动和运行:http: //blog.springsource.com/2010/09/29/new-spring-integration-samples/

希望有帮助。-标记

于 2010-11-30T15:17:05.193 回答
0

问题不在于春天。我认为您将需要一个队列,其中包含包含请求并提供响应的元素。但是响应需要阻塞,直到元素被出列并处理。所以队列元素看起来像:

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

Web 服务入队创建 BlockingPair 及其请求正文。然后将 BlockingPair 元素推入队列。之后它会创建从 BlockingPair 获取响应主体的响应,但会阻塞。

消费者从队列中取出一个 BlockingPair 并设置响应正文。Web 服务从那里继续写入响应。

您需要三个 bean:webservice、阻塞队列和消费者。webservice 和 consumer 都需要队列作为 bean 属性。

队列和消费者 bean 需要在应用程序上下文中进行规划(由 初始化ContextLoaderListener)。队列需要一个 bean id 才能被 web 服务引用(它有自己的上下文,但应用程序上下文作为父级,因此可以引用队列引用):

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

网络服务有自己的上下文定义,这里service-servlet.xml

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

有关定义 spring ws 端点的更多信息,请参阅spring 教程

消费者需要是后台任务,所以我更喜欢石英,弹簧集成见这里

于 2009-04-28T16:07:31.793 回答