Spring integration Spring集成-屏障
我有一个线程,它使用网关(void)将消息发送到两个(pub/sub):Spring integration Spring集成-屏障,spring-integration,Spring Integration,我有一个线程,它使用网关(void)将消息发送到两个(pub/sub): 屏障,用于在实际执行期间保持线程(需要reply=“true”timeout=“XXXX”,output channel=“nullChannel” 以及 拆分器,它接下来将拆分作为消息发送给带有轮询器和线程执行器的服务激活器(直接通道),以进行实际处理/执行 如何正确配置对执行器线程可能引发的异常的处理,并在下面的catch块中捕获它们: try { gateway.trigger() } catch
- 屏障,用于在实际执行期间保持线程(需要reply=“true”timeout=“XXXX”,output channel=“nullChannel”
- 拆分器,它接下来将拆分作为消息发送给带有轮询器和线程执行器的服务激活器(直接通道),以进行实际处理/执行
try {
gateway.trigger()
} catch (ReplyRequiredException e) {
//fine here
} catch (Throwable t) {
// catch every exception here... or somehow configure these exceptions to discard the thread that waits on the barrier and throw below business exception
throw new SomeExecutionFailedException()
}
编辑
<!--gateway.trigger()—>
<int:gateway id=“gateway"
service-interface="com.Gateway"
default-request-channel=“channel1"
default-reply-timeout="0"/>
<int:publish-subscribe-channel id=“channel1"/>
<int:splitter input-channel=“channel1" output-channel=“channel2"
order="1">
<bean class=“com.Splitter"/>
</int:splitter>
<int:barrier id=“barrier" input-channel=“channel1"
output-channel="nullChannel"
correlation-strategy-expression=“'XXX’” <!--hack here-->
requires-reply="true"
timeout=“40000"
order="2">
</int:barrier>
<int:channel id=“channel2">
<int:queue capacity="30"/>
</int:channel>
<!— actual processing/execution —>
<int:service-activator id=“executionAct" input-channel=“channel2"
output-channel=“channel3" ref=“executionService">
<int:poller fixed-rate="111" time-unit="MILLISECONDS" max-messages-per-poll="22"
task-executor=“exec"/>
</int:service-activator>
<bean id=“executionService" class=“com.SomeExecService"/>
<bean id=“exec" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="threadFactory" ref=“execFactory"/>
...
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy"/>
</property>
</bean>
<bean id=“execFactory"
class="org.springframework.scheduling.concurrent.CustomizableThreadFactory">
...
</bean>
<int:channel id=“channel3"/>
<int:chain input-channel=“channel3" output-channel=“channel4">
...
<int:aggregator
group-timeout=“30000"
discard-channel=“discardChannel" release-strategy=“com.ReleaseStrategy"
send-partial-result-on-expiry="false">
<bean class="com.Aggregator"/>
</int:aggregator>
</int:chain>
<int:channel id=“discardChannel”/>
<int:channel id=“channel4"/>
<!— processing done - wake up barrier —>
<int:service-activator id=“barrierReleaseAct" input-channel=“channel4" output-channel="nullChannel">
<bean class="com.ServiceThatSendsXXXMessageToChannel5ToReleaseBarrier"/>
</int:service-activator>
<int:channel id=“channel5"/>
<int:outbound-channel-adapter channel=“channel5"
ref=“barrier" method="trigger"/>
需要回复=“true”
超时=“40000”
order=“2”>
...
...
您需要提供更多的信息、配置等
什么会释放障碍,何时释放
是否要将异常传播到主线程
如果多个拆分失败等,该怎么办
一般的答案是发送一条带有Throwable
有效载荷的消息到屏障的触发器
方法将通过抛出MessaginException
释放线程,并将Throwable
作为其原因。网关打开MessaginException
并抛出原因(这是发送到屏障触发方法的原始有效载荷)
编辑
<!--gateway.trigger()—>
<int:gateway id=“gateway"
service-interface="com.Gateway"
default-request-channel=“channel1"
default-reply-timeout="0"/>
<int:publish-subscribe-channel id=“channel1"/>
<int:splitter input-channel=“channel1" output-channel=“channel2"
order="1">
<bean class=“com.Splitter"/>
</int:splitter>
<int:barrier id=“barrier" input-channel=“channel1"
output-channel="nullChannel"
correlation-strategy-expression=“'XXX’” <!--hack here-->
requires-reply="true"
timeout=“40000"
order="2">
</int:barrier>
<int:channel id=“channel2">
<int:queue capacity="30"/>
</int:channel>
<!— actual processing/execution —>
<int:service-activator id=“executionAct" input-channel=“channel2"
output-channel=“channel3" ref=“executionService">
<int:poller fixed-rate="111" time-unit="MILLISECONDS" max-messages-per-poll="22"
task-executor=“exec"/>
</int:service-activator>
<bean id=“executionService" class=“com.SomeExecService"/>
<bean id=“exec" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="threadFactory" ref=“execFactory"/>
...
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy"/>
</property>
</bean>
<bean id=“execFactory"
class="org.springframework.scheduling.concurrent.CustomizableThreadFactory">
...
</bean>
<int:channel id=“channel3"/>
<int:chain input-channel=“channel3" output-channel=“channel4">
...
<int:aggregator
group-timeout=“30000"
discard-channel=“discardChannel" release-strategy=“com.ReleaseStrategy"
send-partial-result-on-expiry="false">
<bean class="com.Aggregator"/>
</int:aggregator>
</int:chain>
<int:channel id=“discardChannel”/>
<int:channel id=“channel4"/>
<!— processing done - wake up barrier —>
<int:service-activator id=“barrierReleaseAct" input-channel=“channel4" output-channel="nullChannel">
<bean class="com.ServiceThatSendsXXXMessageToChannel5ToReleaseBarrier"/>
</int:service-activator>
<int:channel id=“channel5"/>
<int:outbound-channel-adapter channel=“channel5"
ref=“barrier" method="trigger"/>
我添加了一个,以展示一种在异步线程上收集异常并使屏障将合并异常抛出回网关调用方的技术。Gary,我添加了配置。目前服务释放屏障…是的,最好是捕获主线程中的所有内容。如果其中一个剥离失败,最好是要阻止其他拆分的执行,抛出异常并通知屏障(主捕获块)。请参阅我的编辑-阻止其他拆分的处理有点困难(并导致聚合器提前释放)但是将异常发送回调用方的基本技术如示例所示。工作正常,因此在更复杂的设置中-执行器线程引发的任何异常都将发送到错误通道=“errors”?我还有一个问题要问splitter-默认情况下,它具有apply sequence=“true”“-为什么要在输入通道=“错误”的链中提取序列详细信息和correlationId”通道?无法将错误直接传递到聚合器通道?正确;错误通道
将获取所有错误。但是,发送到通道的错误消息
是一条新的消息
,有效负载为MessaginException
。由于它是一条新消息,因此不会从失败的me继承头消息(在其他情况下,这是有重要原因的)。相反,错误消息负载有两个属性,failedMessage
和cause
。在路由到聚合器之前,标头enricher实际上是说:“我想用其他结果(好或坏)聚合此错误消息。”用于拆分器发出的关联消息”。