代码之家  ›  专栏  ›  技术社区  ›  Lucas Oliveira

异步流中出站网关上的错误处理

  •  2
  • Lucas Oliveira  · 技术社区  · 7 年前

    我有一个这样的集成流程:

    @Bean
    public IntegrationFlow inboundRequestFlow()
    {
        return IntegrationFlows.from( inboundRequestGateway() )
            .log( ... )
            .filter(  requestValidator,
                spec -> spec.discardChannel( invalidRequestChannel() ) )
            .bridge( spec -> spec.requiresReply( false ) )
            .channel( asyncFlowChannel )
            .wireTap(
                //sends a NO_CONTENT reply if the request is ok
                flow -> flow.enrichHeaders( spec -> spec.header( HttpHeaders.STATUS_CODE, HttpStatus.NO_CONTENT ).defaultOverwrite( true ) )
                    .transform( payload -> "" )
                    .channel( inboundGatewayReplyChannel() )
            ).get();
    
    }
    

    它在http网关上接收请求,对其进行验证,如果一切正常,则将请求发送到“asyncFlowChannel”,并用204回复入站网关。

    “asyncFlowChannel”是在执行器通道上运行的另一个IntegrationFlow的起点:

    @Bean
    public IntegrationFlow outboundFlow()
    {
        return IntegrationFlows.from( asyncFlowChannel)
            .log( ... )
            .transform( ... )
            .transform( ... )
            .split(... )            
            .resequence( ... )
            .enrichHeaders( ... )
            .log( ... )
            .transform( ... )
            .handle( this.outboundSOAPGateway() )
            .log( .. )
            .handle( ... )
            .bridge( spec -> spec.requiresReply( false ) )
            .channel( anotherAsyncFlowChannel )
            .get();
    }
    

    如果outboundGateway上发生异常(由于网络相关IO错误或错误响应),我希望记录错误并采取适当措施。但我无法在启动流的outboundSOAPGateway和inboundRequestGateway上设置错误通道,因为它们已经收到了响应。

    我得到的唯一错误线索是以下日志:

    10: 19:53.002警告【outbound-flow-0】组织。springframework。消息传递。果心GenericMessageTemplate$TemporaryReplyChannel-已收到回复消息,但接收线程已收到回复:ErrorMessage[有效负载=…,标头=…]

    我的问题是:在异步流中,如果启动流的inboundGateway已经收到了它的回复,那么处理出站网关错误的正确方法是什么?

    2 回复  |  直到 7 年前
        1
  •  3
  •   Artem Bilan    7 年前

    任何 MessageHandler 端点可以随 AbstractRequestHandlerAdvice . 其中之一是 ExpressionEvaluatingRequestHandlerAdvice 您可以捕获异常并将其发送到 failureChannel : https://docs.spring.io/spring-integration/docs/5.0.0.RELEASE/reference/html/messaging-endpoints-chapter.html#expression-advice .

    为此 .handle( this.outboundSOAPGateway() ) 可以与第二个参数一起提供,例如:

    .handle((GenericHandler<?>) (p, h) -> {
                        throw new RuntimeException("intentional");
                    }, e -> e.advice(retryAdvice()))
    

    在这种情况下,我使用

    @Bean
    public RequestHandlerRetryAdvice retryAdvice() {
        RequestHandlerRetryAdvice requestHandlerRetryAdvice = new RequestHandlerRetryAdvice();
        requestHandlerRetryAdvice.setRecoveryCallback(new ErrorMessageSendingRecoverer(recoveryChannel()));
        return requestHandlerRetryAdvice;
    }
    

    但同样适用于 表达式EvaluationRequestHandlerAdvice .

    顺便说一句 retryAdvice() 可能也会对你有好处。查看其 ErrorMessageSendingRecoverer .

        2
  •  1
  •   Gary Russell    7 年前

    而不是 .channel( asyncFlowChannel ) 使用

    .gateway(asyncFlowChannel, e -> e.errorChannel(...))