我有两个出站网关,它们的数据和格式相似但不相同。我想用一个作为备用,以防doesn没有回复或回复太长。另外,在将来,我希望可以选择从哪个网关获取数据。(因此,我希望将其作为单独的出站网关,我看到了带有重试建议的示例,并希望避免这种变体)
在非常简单的模式下,我使用错误通道作为备用网关的输入通道。完美工作,直到替代网关也出现故障,然后我会收到:
org.springframework.integration.MessagingException: failure occurred in error-handling flow在堆栈跟踪中出现这种情况有一个真正的原因(连接超时或任何原因),但对我来说似乎并不令人满意,因为我希望以不同的方式处理一些异常类型。我希望从备用网关获得错误消息(和异常),而不是包装的网关。
有没有办法让它正确,或者我在架构上完全错了?
发布于 2013-12-27 23:47:44
看起来你想实现一个failover pattern。为此,您可以简单地将两个端点订阅到同一通道,但不需要load-balancing
<channel id="input">
<dispatcher load-balancer="none"/>
</channel>
<service-activator input-channel="input" ref="service1"/>
<service-activator input-channel="input" ref="service2"/>在这种情况下,如果第一个<service-activator>由于某种原因失败,消息将被传递到第二个。
并且没有理由使用retry,或者尝试从错误处理中重新建立流。
更新:
要跳过某些异常并故障转移到下一个订阅者,您可以使用一些自定义RequestHandlerAdvice(Expression Evaluating Advice):
class ExceptionProviderRequestHandlerAdvice extends ExpressionEvaluatingRequestHandlerAdvice {
@Override
protected Object doInvoke(AbstractRequestHandlerAdvice.ExecutionCallback callback, Object target, Message<?> message) throws Exception {
def result = super.doInvoke(callback, target, message)
if (result in Exception) {
throw result
}
return result
}}
你的onFailureExpression应该决定:是否为重新抛出返回异常:
<int:request-handler-advice-chain>
<beans:bean class="com.cs.otppr.core.aop.ExceptionProviderRequestHandlerAdvice">
<beans:property name="returnFailureExpressionResult" value="true"/>
<beans:property name="onFailureExpression"
value="#exception instanceof T (com.my.proj.MyException) ? #exception : null"/>
</beans:bean>
</int:request-handler-advice-chain>当然,您也可以尝试自己找到解决方案……
发布于 2014-01-02 21:34:32
我找到了一个适合我的解决方案,不确定它是否合适,但目前它满足了所有建议的未来需求。我将我的出站网关分成两个具有独立错误通道的段,其中第一个的错误通道是第二个的输入。我可以处理来自两个出站的错误,路由异常,并且在我看来很容易进一步添加一些逻辑。在两个出站网关都失败的情况下,将只收到最后一个网关异常,但这适合我,因为我不需要汇总这些错误。当然,更多的建议也会被欣然接受。
app-config.xml如下所示
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:elasticsearch="http://www.pilato.fr/schema/elasticsearch"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-3.0.xsd
http://www.pilato.fr/schema/elasticsearch http://www.pilato.fr/schema/elasticsearch/elasticsearch-0.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<int-http:inbound-gateway id="inboundController"
request-channel="requests"
reply-channel="replies-f"
path="/item_info"
supported-methods="GET"
payload-expression="#requestParams"
>
<int-http:request-mapping
params="id"/>
</int-http:inbound-gateway>
<int-http:outbound-gateway id="simpleGateway"
request-channel="outboundRequests"
reply-channel="replies-f"
http-method="GET"
expected-response-type="com.dph.iteminfo.transformer.ItemInfoDTO"
url="http://10.5.4.134:8080/ess/iteminfo?id={itemId}&group_size={groupSize}"
>
<int-http:uri-variable name="itemId" expression="payload.get('id')[0]"/>
<int-http:uri-variable name="groupSize" expression="payload.containsKey('group_size') ? payload.get('group_size')[0] : 5"/>
</int-http:outbound-gateway>
<int-http:outbound-gateway id="alternativeSource"
request-channel="altOutboundChannel"
reply-channel="replies-f"
http-method="GET"
expected-response-type="java.lang.String"
url="http://10.5.4.134:8080/ess/iteminfo?id={itemId}&len={groupSize}"
>
<int-http:uri-variable name="itemId" expression="payload.get('id')[0]"/>
<int-http:uri-variable name="groupSize" expression="payload.containsKey('group_size') ? payload.get('group_size')[0] : 5"/>
</int-http:outbound-gateway>
<int:service-activator input-channel="requests" ref="outboundMain"/>
<int:gateway id="outboundMain" default-request-channel="outboundRequests" error-channel="altChannel" />
<int:exception-type-router default-output-channel="replies-f" input-channel="altChannel">
<int:mapping exception-type="org.springframework.web.client.HttpServerErrorException" channel="resendableMessagesChannel"/>
<int:mapping exception-type="org.springframework.web.client.ResourceAccessException" channel="resendableMessagesChannel"/>
</int:exception-type-router>
<int:service-activator input-channel="resendableMessagesChannel" ref="resender"/>
<int:gateway id="resender" default-request-channel="processedErrorsChannel" error-channel="finalErrors"/>
<int:transformer input-channel="processedErrorsChannel" output-channel="altOutboundChannel" expression="payload.getFailedMessage().getPayload()" />
<int:bridge input-channel="finalErrors" output-channel="replies-f"/>
<!-- will be error processing here -->
<int:channel id="finalErrors" />
<int:channel id="requests" />
<int:channel id="replies-f" />
</beans>https://stackoverflow.com/questions/20803274
复制相似问题