我有以下工作流程。
入站信道
分离器
分割渠道的任务执行者 - 所有线程都执行相同的工作流程。
3.A。构建请求
3.B。网关消息端点的服务激活包装器。
3.C。 http-outbound-gateway上的网关包装器,配置了error-channel(在调用http-outbound-gateway时处理异常)
3.D。 HTTP的出站网关
聚合
弹出整合工作流程的响应。
如果在3.d中发生异常,则控制转到为网关错误通道配置的服务激活器。 我将失败的消息中的以下内容复制到传递给错误通道的标头的新标题。
一个。的correlationID 湾序列号 C。 sequenceSize
但是在聚合拆分器响应时,DefaultAggregatingMessageGroupProcessor.java会删除冲突的标头,并在将控制权提供给聚合器之前删除错误通道和回复通道。
因此,一旦聚合器完成它的操作,它就无法找到回复或错误通道,并导致异常。
我使用的是spring-integration-core版本2.2.1,我不确定为什么在标头聚合期间删除了回复通道和错误通道。
有关解决此问题的任何意见都会有很大帮助。
谢谢你:)
编辑1: 非常感谢Gary帮我解决这个问题。我正在分享我当前的配置
<!-- SPLITTER -->
<int:splitter id="dentalSplitter" ref="dentalServiceSplitter"
method="getDentalServiceList" input-channel="dentalServiceSplitterChannel"
output-channel="dentalSplitterTaskChannel" />
<int:channel id="dentalSplitterTaskChannel">
<int:dispatcher task-executor="dentalTaskExecutor" />
</int:channel>
<int:chain input-channel="dentalSplitterTaskChannel" output-channel="dentalGatewayChannel">
<int:header-enricher>
<int:header name="CHAIN_START_TIME" expression="T(System).currentTimeMillis()" overwrite="true" />
<int:object-to-json-transformer content-type="application/json"/>
</int:chain>
<int:service-activator input-channel="dentalGatewayChannel" ref="dentalGatewayWrapper" output-channel="dentalReplyChannel" />
<int:gateway id="dentalGatewayWrapper" default-request-channel="dentalCostEstimateRequestChannel" error-channel="dentalErrorChannel"/>
<int-http:outbound-gateway id="dentalGateway"
url-expression="@urlBuilder.build('${service.endpoint}')"
http-method="POST" request-factory="clientHttpRequestFactory"
request-channel="dentalCostEstimateRequestChannel" extract-request-payload="true"
expected-response-type="com.dental.test.DentalResponse">
<int-http:request-handler-advice-chain>
<ref bean="logChainTimeInterceptor" />
</int-http:request-handler-advice-chain>
</int-http:outbound-gateway>
<!-- EXCEPTION -->
<int:chain input-channel="dentalErrorChannel" output-channel="dentalAggregatorChannel">
<int:transformer ref="commonErrorTransformer" method="dentalGracefulReturn"/>
</int:chain>
<!-- SUCCESS -->
<int:chain input-channel="dentalReplyChannel" output-channel="dentalAggregatorChannel">
<int:filter discard-channel="dentalErrorChannel"
expression="T(com.dental.util.InvocationOutcomeHelper).isOutcomeSuccess(payload?.metadata?.outcome?.code,payload?.metadata?.outcome?.message)" />
</int:chain>
<!-- AGGREGATION -->
<int:chain input-channel="dentalAggregatorChannel" output-channel="wsDentalServiceOutputChannel" >
<int:aggregator ref="dentalServiceAggregator" />
<int:service-activator ref="dentalResponseServiceActivator" />
</int:chain>
我注意到这一点,每个分割通道在通过网关时都会创建一个新的临时通道以进行错误和回复,并在从网关获得响应后,它会保留保留的(原始入站)错误和回复通道标头。正如您所提到的,在控制进入错误转换器之后,保留已保留标头的流被破坏,聚合消息组处理器接收三个不同的临时通道实例,从而将其删除。 我计划有一个自定义消息组处理器并修改冲突解决策略以聚合标头,并提出了这个配置。
<bean id="channelPreservingAggregatingMessageHandler" class="org.springframework.integration.aggregator.AggregatingMessageHandler">
<constructor-arg name="processor" ref="channelPreservingMessageGroupProcessor"/>
</bean>
我还没试过这个。但基于此讨论,这似乎不是一个可行的解决方案。
看起来我在网关中进行错误处理的配置不正确。 但是,我对你的这个陈述感到困惑&#34;而不是直接转发消息,只需处理错误流上的错误并将结果正常返回给网关&#34;包装&#34;&# 34 ;.如果我删除错误通道,如何在发生异常时将控制权恢复?可能是我在这里不了解某事。你能详细说明一下吗?
答案 0 :(得分:3)
在询问有关此类方案的问题时,通常需要显示您的配置。但是,我怀疑您是将错误流中的消息直接转发给聚合器。
这就像在代码中执行GOTO
并打破范围。
它不起作用,因为错误消息中的replyChannel
标头是针对网关&#34;包装器&#34;而不是原始上游入站网关。当聚合器获得冲突的标头时,它别无选择,只能删除标头(您将看到一条DEBUG日志消息)。
不是直接转发消息,而是简单地处理错误流上的错误并将结果正常返回到网关&#34;包装器&#34; (只是省略错误流上最后一个元素的错误通道。)
然后网关将修复回复,使其与其他消息(好的和坏的)保持一致,并将其转发给聚合器。
您不需要在错误流程中弄乱标题,只需返回要聚合的值以及良好的结果。
你应该真正更新到current release,或至少更新到2.2.x一行(2.2.6)。