我们有以下春季整合流程:
jms消息驱动的频道适配器 - > ... - >发布/订阅频道 - > 3 预订的富集者 - >聚合器 - > ...
每个浓缩器都指定了task-scheduler
,因此它们并行工作。
不幸的是,这种方法不能正常工作,因为原始的JMS线程丢失了。
我希望jms-message-driver-channel-adapter
和aggregator
在同一个帖子中运行,但是aggregator
(以及后续处理程序)在“last”richher thread中运行。
我怎样才能做到这一点?我没有在spring-int
文档中的任何地方看到这个。
在Gary回复后添加
我决定以更自然的方式实现这一点:
<int:service-activator method="enrich" input-channel="in" output-channel="out">
<bean class="com.xxx.ParallelEnricher" p:timeoutMs="10000">
<constructor-arg ref="taskExecutor" />
<constructor-arg>
<list>
<bean class="com.xxx.Enricher1" />
<bean class="com.xxx.Enricher2" />
<bean class="com.xxx.Enricher3" />
</list>
</constructor-arg>
</bean>
</int:service-activator>
其中ParallelEnricher是一个可重用的类,它为每个richr调用“Future taskExecutor.submit(Runnable)”并处理超时。 可能是我遗漏了一些东西,但在同一条消息上配置并行操作会很好:
<int:service-activator method="enrich" input-channel="in" output-channel="out"
timeout="10000" task-executor="taskExecutor">
<list>
<bean class="com.xxx.Enricher1" />
<bean class="com.xxx.Enricher2" />
<bean class="com.xxx.Enricher3" />
</list>
</int:service-activator>
答案 0 :(得分:1)
一种解决方案是添加网关中间流;这样,JMS线程将等待来自最终消费者的回复 - 它必须返回“某事”(只是离开他的output-channel
并且框架将回复到网关,在那里它可以被丢弃) ...
<int:service-activator input-channel="fromJMS" output-channel="nullChannel"
ref="gw" />
<int:gateway default-request-channel="myPubSub" />
只需确保最终消费者(可能是在聚合器之后的某个地方)发送回复(无论它是什么;它将被发送到nullChannel
将被丢弃。)
请注意,默认情况下线程会无限期地等待;如果你需要超时并回滚消息,你将需要额外的逻辑。
另一种解决方案是添加第四个订阅者,这是receive()
来自QueueChannel
的简单服务。同样,最终消费者发送消息以触发释放。您需要在pub / sub之前添加标头,以便为每条消息添加新的QueueChannel
标头(<int:header name="myReleaseTriggerChannel" expression="new ...QueueChannel()"/>
;最终消费者会向该标头发送“内容”(可能是简单的路由器)。
此解决方案需要一些用户代码(从队列中接收),但以这种方式处理超时更容易。