简体   繁体   English

错误消息处理行为,Spring集成

[英]Error message handling behaviour, spring integration

Im having 2 outbound gateways with similar but not equal data and format. 我有2个出站网关,它们具有相似但不相等的数据和格式。 I'd want to use one as alternative in case 1st doesn't reply or reply too long. 如果第1次回复或回复时间过长,我想将其中一个用作替代方法。 Also in future I want to have option to choose which one to get data from.(So Id like to have it as separate outbound gateway, I saw examples with retry advices and would like to avoid this variant) 将来我也希望可以选择从哪一个数据中获取数据(因此我想将其作为单独的出站网关,我看到了带有重试建议的示例,并希望避免这种变化)

Atm at very simplified schema I use error channel as incoming channel of alternative gateway. 在非常简化的架构下的atm,我将错误通道用作备用网关的传入通道。 Works perfect until alternative gateway fails too, then I receive: 完美运行,直到替代网关也失败,然后我收到:

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

There's a real reason of this (connection timeout or any) in stacktrace, but it seems not satisfying for me, since i'd like to handle some exception types differently. 在stacktrace中有一个真正的原因(连接超时或任何超时),但对我来说似乎并不令人满意,因为我想以不同的方式处理某些异常类型。 I'd like to get error message (and exception) from alternative gateway, not wrapped one. 我想从替代网关(而不是包装网关)获取错误消息(和异常)。

Is there any way to get it right or Im totally wrong in architecture of this? 在此架构中,有什么方法可以做到正确或完全错误?

Looks like you want to achieve a failover pattern . 看起来您想实现failover pattern For this purpose you can simply subscribe both endpoints to the same channel, but without load-balancing : 为此,您可以简单地将两个端点都订阅到同一通道,而无需进行load-balancing

<channel id="input">
    <dispatcher load-balancer="none"/>
</channel>

<service-activator input-channel="input" ref="service1"/>

<service-activator input-channel="input" ref="service2"/>

In this case, if the first <service-activator> will fail by some reason, the Message will be delivered to the second one. 在这种情况下,如果第一个<service-activator>由于某种原因而失败,则消息将被传递到第二个。

And there is no reason to use retry , or try to reestablish flow from error handling. 并且没有理由使用retry或尝试从错误处理中重新建立流。

UPDATE: 更新:

To skip some exceptions and do failover to the next subscriber you can use some custom RequestHandlerAdvice ( Expression Evaluating Advice ): 要跳过某些异常并进行故障转移到下一个订阅者,可以使用一些自定义RequestHandlerAdvice表达式评估建议 ):

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
}

} }

And your onFailureExpression should decide: to return exception for rethrow or not: 您的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>

Or, of course, you can try to find solution on your own... 或者,当然,您可以尝试自己寻找解决方案...

found a solution that suits me, not sure its proper one, but for now it satisfies all suggested future requirements. 找到了适合我的解决方案,虽然不确定它是否合适,但目前可以满足所有建议的将来要求。 I separated my outbound gateways to 2 segments with independent error channels, where error channel of first is input of second. 我将出站网关分为两个具有独立错误通道的网段,其中第一个错误通道是第二个错误输入。 I can process errors from both outbounds, route exceptions and as seems to me easily add some logic futher. 我可以处理两个出站,路由异常中的错误,而且在我看来,可以轻松地添加一些逻辑。 In case of both outbound gateway fails there will be only last gateway exception recieved but that suits me since i dont need to aggregate those errors. 如果两个出站网关均发生故障,则只会收到最后一个网关异常,但这很适合我,因为我不需要汇总这些错误。 More suggestions are gladly accepted of course. 当然,我们很乐意接受更多建议。

app-config.xml looks like this 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何绑定Spring集成错误处理和RabbitMQ错误处理以使消息重新排队失败并带有一些跳过的异常? - How to tie up Spring integration error handling and RabbitMQ error handling to requeue message failed with some skipped exception? AMQP Spring Integration错误处理 - AMQP Spring Integration error handling Spring集成流异步中的错误处理 - Error handling in Spring integration flow async 在 Spring Integration 中使用 Http Outbound Gateway 进行错误处理 - Error handling with Http Outbound Gateway in Spring Integration Spring集成流程中的错误处理实践 - Error handling practices in spring integration flow Spring Integration中的错误处理期间的MessageTransformation异常 - MessageTransformation exception during error handling in Spring Integration Spring Integration中的AffinityThreadFactory错误消息是什么? - What is the AffinityThreadFactory error message in spring integration? Java消息对象枚举Spring集成错误 - Java Message Object Enum Spring integration Error Spring Integration:错误通道 - 异常处理问题 - Spring Integration: error-channel - Problems with exception handling 为什么在默认的 Spring Cloud Stream 配置中更改了 Spring Integration 消息方法处理行为 - Why Spring Integration message method handling behavoiur is changed in default Spring Cloud Stream configuration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM