简体   繁体   English

为什么Spring Integration故障转移没有显示异常

[英]Why Spring Integration failover doesn't show exception

I have some problem with Spring Integration dispatcher's failover that should show me Exception if my Message Handler fails. 我对Spring Integration分派器的故障转移有一些问题,如果我的消息处理程序失败,应该向我显示异常。

I have simple Spring integration context: 我有简单的Spring集成上下文:

<int:gateway default-request-channel="inboundChannel"
             service-interface="com.some.gateway.PrinterGateway"/>

    <int:channel id="inboundChannel">
        <int:dispatcher failover="false"/>
    </int:channel>

    <!--first Message Handler (broken)-->    
    <bean id="printService" class="com.some.service.PrinterService"/>

    <int:service-activator input-channel="inboundChannel"
                           method="print"
                           ref="printService"/>

    <!--second Message Handler-->
    <bean id="uppercasePrintService"
          class="com.some.service.UppercasePrinterService"/>

    <int:service-activator input-channel="inboundChannel"
                           method="printUppercase"
                           ref="uppercasePrintService"/>

And my broken Message Handler class: 和我坏了的消息处理程序类:

public class PrinterService {

    public void print(Message<String> message) {
        throw new RuntimeException("This is error");
    }
}
  1. Can you explain me why my failover don't work? 您能解释一下为什么我的故障转移不起作用吗?
  2. Why RuntimeException is skipped and message was delivered to the next handler? 为什么会跳过RuntimeException并将消息传递到下一个处理程序?

It works fine for me. 这对我来说可以。

It's not clear what you are trying to achieve; 目前尚不清楚您要达到的目标。 perhaps you misunderstand the load balancing? 也许您误解了负载平衡?

By default, the load balancing strategy is round-robin, which means the first message will go to the failing endpoint; 默认情况下,负载平衡策略是轮询,这意味着第一条消息将到达故障端点; the second will go to the good endpoint. 第二个将转到良好的端点。 Messages will alternate. 消息将交替显示。

19:23:16.867 [main] DEBUG org.springframework.integration.channel.DirectChannel - preSend on channel 'org.springframework.integration.channel.DirectChannel@1794d431', message: GenericMessage [payload=foo, headers={id=9c3b1493-0a9a-e324-6da3-262079677ed0, timestamp=1494199396867}]
org.springframework.messaging.MessageDeliveryException: failed to send Message to channel 'null'; nested exception is java.lang.RuntimeException: foo, failedMessage=GenericMessage [payload=foo, headers={id=9c3b1493-0a9a-e324-6da3-262079677ed0, timestamp=1494199396867}]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:449)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
    at com.example.So43836561Application.main(So43836561Application.java:16)
Caused by: java.lang.RuntimeException: foo
    at com.example.So43836561Application.lambda$0(So43836561Application.java:13)
    at com.example.So43836561Application$$Lambda$1/1121454968.handleMessage(Unknown Source)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:160)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
    ... 2 more
19:23:18.875 [main] DEBUG org.springframework.integration.channel.DirectChannel - preSend on channel 'org.springframework.integration.channel.DirectChannel@1794d431', message: GenericMessage [payload=bar, headers={id=90aaa16c-a8c1-9162-ba8f-532fa3201c7f, timestamp=1494199398875}]
Second Service: GenericMessage [payload=bar, headers={id=90aaa16c-a8c1-9162-ba8f-532fa3201c7f, timestamp=1494199398875}]
19:23:18.876 [main] DEBUG org.springframework.integration.channel.DirectChannel - postSend (sent=true) on channel 'org.springframework.integration.channel.DirectChannel@1794d431', message: GenericMessage [payload=bar, headers={id=90aaa16c-a8c1-9162-ba8f-532fa3201c7f, timestamp=1494199398875}]

If you use a NONE load balancing strategy, all messages will go to the failing one. 如果您使用NONE负载平衡策略,则所有消息将转到失败的消息中。

19:26:38.005 [main] DEBUG org.springframework.integration.channel.DirectChannel - preSend on channel 'org.springframework.integration.channel.DirectChannel@7d9d1a19', message: GenericMessage [payload=foo, headers={id=6a69efe9-dbbd-c79b-41a9-6964fd4c8ccc, timestamp=1494199598004}]
org.springframework.messaging.MessageDeliveryException: failed to send Message to channel 'null'; nested exception is java.lang.RuntimeException: foo, failedMessage=GenericMessage [payload=foo, headers={id=6a69efe9-dbbd-c79b-41a9-6964fd4c8ccc, timestamp=1494199598004}]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:449)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
    at com.example.So43836561Application.main(So43836561Application.java:16)
Caused by: java.lang.RuntimeException: foo
    at com.example.So43836561Application.lambda$0(So43836561Application.java:13)
    at com.example.So43836561Application$$Lambda$1/2009787198.handleMessage(Unknown Source)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:160)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
    ... 2 more
19:26:40.009 [main] DEBUG org.springframework.integration.channel.DirectChannel - preSend on channel 'org.springframework.integration.channel.DirectChannel@7d9d1a19', message: GenericMessage [payload=bar, headers={id=9428a10e-3a17-79d5-e4bd-731fc88ef0fe, timestamp=1494199600008}]
Exception in thread "main" org.springframework.messaging.MessageDeliveryException: failed to send Message to channel 'null'; nested exception is java.lang.RuntimeException: foo, failedMessage=GenericMessage [payload=bar, headers={id=9428a10e-3a17-79d5-e4bd-731fc88ef0fe, timestamp=1494199600008}]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:449)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
    at com.example.So43836561Application.main(So43836561Application.java:22)
Caused by: java.lang.RuntimeException: foo
    at com.example.So43836561Application.lambda$0(So43836561Application.java:13)
    at com.example.So43836561Application$$Lambda$1/2009787198.handleMessage(Unknown Source)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:160)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
    ... 2 more

If that's not the problem, perhaps you have a second channel bean, with the same id that's configured differently? 如果这不是问题,那么也许您还有另一个Channel Bean,其ID的配置有所不同?

Regardless, turning on DEBUG logging for org.springframework.integration will show you what's going on. 无论如何,为org.springframework.integration打开DEBUG日志将向您显示正在发生的事情。

EDIT 编辑

Since you are using an async gateway (returns Future<?> ) you need to examine the result to get the exception... 由于您使用的是异步网关(返回Future<?> ),因此您需要检查结果以获取异常...

@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
    List<Future<Message<String>>> futures = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        Message<String> message = MessageBuilder.withPayload("Some payload that created for message id: " + i)
                .build();
        log.info("Sending message " + i);
        futures.add(gateway.print(message));
    }
    futures.forEach(f -> {
        try {
            System.out.println(f.get());
        }
        catch (ExecutionException e) {
            System.out.println(e.getCause().getMessage());
        }
        catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    });
}

and

public String printUppercase(Message<String> message) {
    log.info(message.getPayload().toUpperCase());
    return message.getPayload().toUpperCase();
}

result: 结果:

This is error
GenericMessage [payload=SOME PAYLOAD THAT CREATED FOR MESSAGE ID: 1, headers={id=229ad2ee-f424-61da-a9bc-a631de9bd5d0, timestamp=1494360966556}]
GenericMessage [payload=SOME PAYLOAD THAT CREATED FOR MESSAGE ID: 2, headers={id=7e2c45c4-2c7b-f3f3-243d-56d9de33375f, timestamp=1494360966556}]
This is error
This is error
This is error
GenericMessage [payload=SOME PAYLOAD THAT CREATED FOR MESSAGE ID: 6, headers={id=79f4ef60-9dea-60f3-3972-a9eefde67ebf, timestamp=1494360966556}]
GenericMessage [payload=SOME PAYLOAD THAT CREATED FOR MESSAGE ID: 7, headers={id=626d1347-e5bd-ec4c-b153-71174cc7f18d, timestamp=1494360966556}]
This is error

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM