【问题标题】:Error message handling behaviour, spring integration错误消息处理行为,spring 集成
【发布时间】:2014-04-23 23:41:12
【问题描述】:

我有 2 个具有相似但不相等的数据和格式的出站网关。如果 1st 没有回复或回复时间过长,我想使用一个作为替代方案。另外,在未来我希望可以选择从哪一个获取数据。(所以我想将它作为单独的出站网关,我看到了带有重试建议的示例,并希望避免这种变体)

Atm 在非常简化的模式下,我使用错误通道作为替代网关的传入通道。在替代网关也失败之前完美运行,然后我收到:

org.springframework.integration.MessagingException: failure occurred in error-handling flow

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

有没有办法让它正确或我在这个架构上完全错误?

【问题讨论】:

    标签: java spring-integration


    【解决方案1】:

    看起来您想获得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"/>
    

    在这种情况下,如果第一个 &lt;service-activator&gt; 由于某种原因失败,消息将被传递到第二个。

    并且没有理由使用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>
    

    或者,当然,您可以尝试自己寻找解决方案...

    【讨论】:

    • 它确实解决了所描述的问题并且看起来很整洁,但我需要一个可能性,只有在出现某些特定错误的情况下才会向“service2”发送消息,我为此使用了异常类型的路由器,不得不提一下从一开始。有什么方法可以用这种方式过滤或路由它?
    • 我找了很多变种,有时间对电路技术的无知感到遗憾,甚至在 EIP 书中找到了关于“基于上下文的路由器”的提及,这在理论上可以完美运行,但据我所知应该是在实践中由我自己实现,并以下面的变体结尾。很可能不是最终的。
    【解决方案2】:

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

    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}&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>
    

    【讨论】:

      猜你喜欢
      • 2020-04-05
      • 2018-08-25
      • 2021-06-09
      • 2013-03-30
      • 1970-01-01
      • 2012-11-21
      • 1970-01-01
      • 2015-05-24
      • 2018-07-05
      相关资源
      最近更新 更多