Spring batch 使用应答目标的分区作业

Spring batch 使用应答目标的分区作业,spring-batch,spring-integration,Spring Batch,Spring Integration,我们有一个JEE应用程序,在集群上使用大约40个分区作业。它可以部署在JBoss和WebSphere上。我们遇到了两个问题: JBoss和WebSphere中的消息传递系统故障通常与临时队列连接问题有关 分区作业由于丢失消息而有效挂起 我读到一篇帖子说,切换出站网关的回复目的地,可以提高健壮性,并允许在出现故障时重新连接。入站网关基本上在请求队列上启动两个侦听器 <int-jms:inbound-gateway id="springbatch.inbound.gateway"

我们有一个JEE应用程序,在集群上使用大约40个分区作业。它可以部署在JBoss和WebSphere上。我们遇到了两个问题:

  • JBoss和WebSphere中的消息传递系统故障通常与临时队列连接问题有关

  • 分区作业由于丢失消息而有效挂起

我读到一篇帖子说,切换
出站网关的
回复目的地
,可以提高健壮性,并允许在出现故障时重新连接。入站网关基本上在请求队列上启动两个侦听器

<int-jms:inbound-gateway id="springbatch.inbound.gateway" 
                connection-factory="springbatch.jmsConnectionFactory" 
                request-channel="springbatch.slave.jms.request" 
                request-destination="requestsQueue" 
                reply-channel="springbatch.slave.jms.response" 
                concurrent-consumers="2" 
                max-concurrent-consumers="2"/> 
它在单个服务器上运行良好,但在集群上运行时,分区会围绕集群运行,但主步骤不会得到确认。我认为
JMSCoordinationID
作为相关键将处理JMS消息的匹配


我是否缺少一个配置块?

您所拥有的应该可以工作;在该模式下,相关id设置为
gatewayId+n
(其中
gatewayId
UUID
的增量)。回复容器消息选择器设置为
JMSCorrelationID LIKE gatewayId%
,因此步骤执行结果应正确路由回主机。我建议您打开
DEBUG
logging并按照两侧的消息查看发生了什么

编辑:

回复:共享JMS端点(评论如下)

这是可以做到的,但需要一些重组

在生产者(主)端,网关和独立聚合器必须移动到父上下文(每个作业上下文都是它的子上下文)。由于分区处理程序必须位于子上下文中,因此需要一个单独的聚合器类;也就是说,聚合与分区是正交的,只是为了方便起见,聚合在bean中。公共聚合器是可以的,因为它使用分区处理程序的相关id来执行作业,并且重新组装的步骤执行结果将被路由到正确的分区处理程序

消费者(从属)端有点棘手,因为如果入站网关位于单个(父)上下文中,它将无法看到子上下文中的
stepExecutionRequestHandler
s'通道;您需要构建一个路由器来将请求路由到适当的作业上下文。不是不可能,只是多一点工作


和它的自述文件是一个很好的起点。

我能够在一台服务器上工作,但仍然在集群上确认。在相关的一点上,因为我们有40多个作业,为了最大限度地减少资源使用,我们可以重用出站网关或侦听器吗?(或者不是因为必须转到单个聚合器?)我在集群队列上看到96个侦听器。似乎对于每个定义的JMSOutboundGateway(定义了回复目的地),都会在服务器启动时创建侦听器。因此,我们看到启动时创建的48 X 2侦听器(每个48个作业和2个侦听器)。我希望侦听器仅在出站网关发送消息时创建。它们是在启动时创建的,而不是为了提高效率吗?默认情况下
auto startup=“true”
。您可以将其覆盖为false,但您需要
start()
它们,可能是从先前的作业步骤(tasklet)开始,并在分区步骤完成时
stop()
它们。您可以通过正常的Springbean连接(
@AutoWired
等)获取对网关(
EventDrivenConsumer
)的引用,或者使用
并发送
@gatewayId.start()
。我添加了一个以添加延迟启动选项。我实现了Gary下面讨论的方法,即利用StepListener并在分区步骤开始时启动出站网关。分区步骤(本地和远程)第一次同时完成。同一作业的第二次运行时,远程步骤完成,而本地或分区步骤未完成。我查看了JBoss回复队列,消息就在那里。我检查了方法
isRunning()
,它说
true
我又运行了一些测试,并注意到在每次JBoss服务器重启后,对任何作业的第一次尝试都会成功。任何作业的后续尝试都会将消息留在队列中,就像没有人在侦听一样。在网关上调用start是否只启动通道而不是队列的侦听器?下面是更多观察结果。在JBoss启动时,我看到回复队列上有0个消费者(来自JBoss JMX)。当我第一次运行批处理时是成功的,但它在回复队列中留下1个消费者。当我第二次运行批处理作业时,使用者的数量保持在1。在中,调试器正在JmsOutboundGateway
reply=replyQueue.poll(this.receiveTimeout,TimeUnit.millides)中的行上等待;与Spring Batch 2.1.8、Spring Integration 2.2.0以及Spring JMS和Framework 3.2.0是否存在可能的兼容性问题?
<int-jms:outbound-gateway 
    connection-factory="springbatch.jmsConnectionFactory" 
    request-channel="jms.channel.1" 
    request-destination="requestsQueue" 
    reply-channel="jms.channel.2" 
    reply-destination="repliesQueue"
    correlation-key="JMSCorrelationID" >
    <int-jms:reply-listener />        
</int-jms:outbound-gateway>