首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误消息处理行为,spring集成

错误消息处理行为,spring集成
EN

Stack Overflow用户
提问于 2013-12-27 23:32:26
回答 2查看 4.7K关注 0票数 1

我有两个出站网关,它们的数据和格式相似但不相同。我想用一个作为备用,以防doesn没有回复或回复太长。另外,在将来,我希望可以选择从哪个网关获取数据。(因此,我希望将其作为单独的出站网关,我看到了带有重试建议的示例,并希望避免这种变体)

在非常简单的模式下,我使用错误通道作为备用网关的输入通道。完美工作,直到替代网关也出现故障,然后我会收到:

代码语言:javascript
复制
org.springframework.integration.MessagingException: failure occurred in error-handling flow

在堆栈跟踪中出现这种情况有一个真正的原因(连接超时或任何原因),但对我来说似乎并不令人满意,因为我希望以不同的方式处理一些异常类型。我希望从备用网关获得错误消息(和异常),而不是包装的网关。

有没有办法让它正确,或者我在架构上完全错了?

EN

回答 2

Stack Overflow用户

发布于 2013-12-27 23:47:44

看起来你想实现一个failover pattern。为此,您可以简单地将两个端点订阅到同一通道,但不需要load-balancing

代码语言:javascript
复制
<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):

代码语言:javascript
复制
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应该决定:是否为重新抛出返回异常:

代码语言:javascript
复制
<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>

当然,您也可以尝试自己找到解决方案……

票数 3
EN

Stack Overflow用户

发布于 2014-01-02 21:34:32

我找到了一个适合我的解决方案,不确定它是否合适,但目前它满足了所有建议的未来需求。我将我的出站网关分成两个具有独立错误通道的段,其中第一个的错误通道是第二个的输入。我可以处理来自两个出站的错误,路由异常,并且在我看来很容易进一步添加一些逻辑。在两个出站网关都失败的情况下,将只收到最后一个网关异常,但这适合我,因为我不需要汇总这些错误。当然,更多的建议也会被欣然接受。

app-config.xml如下所示

代码语言:javascript
复制
<?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}&amp;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}&amp;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>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20803274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档