无法订阅全局errorChannel

时间:2019-04-02 21:37:36

标签: spring spring-integration spring-cloud-stream

我有两个应用程序,它们使用Spring Cloud流和rabbitmq绑定器相互抛出消息。我无法订阅全局或专用错误通道。我确定我错过了对Spring框架之神之一的注解祈祷。

我试图将代码简化为以下内容。 (代码也可以在https://github.com/achintmehta/springclouddemo上获得)

在下面的代码中,我试图向INPUT通道发送一条消息,并在OUTPUT通道上返回一条消息。 INPUT通道的流侦听器引发异常,我看到logHandler打印该异常,但是没有调用我的所有注册端点来出错。

    public static void main(String[] args) {
        SpringApplication.run(SprintclouddemoApplication.class, args);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // Send a message to INPUT Channel
        System.out.println("****************** Inside run method *********************");
        source.input().send(
                        MessageBuilder
                       .withPayload("ACTIVE")
                           .build());
    }

    @StreamListener(Processor.INPUT)
    @SendTo(Processor.OUTPUT)  // Send back the response to OUTPUT channel
    public String requestReceived(
            String state) {
        // Receive message on input channel
        System.out.println("****************** Received event *********************");
        // Throw exception
        throw new RuntimeException("!!!!! ABORT ABORT !!!!!");
        //return "Event received";
    }

    @StreamListener(Processor.OUTPUT)
    public void responseReceived(Message<?> message) {
        // Listen for message on OUTPUT channel
        System.out.println("******************* ACK received as : " + message);
    }

    @ServiceActivator(inputChannel="errorChannel")
    public ErrorMessage onError(ErrorMessage message) {
        // THIS FUNCTION NEVER GETS CALLED WHEN EXCEPTION HAPPENS
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Received ERROR: " + message);
        return message;
    }

    @StreamListener("errorChannel")
    public void error(Message<?> message) {
        // THIS FUNCTION NEVER GETS CALLED WHEN EXCEPTION HAPPENS
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Handling ERROR: " + message);
    }




以下是我的application.yml文件

 spring:
  application:
    name: cloudstream-demo

  rabbitmq:
    host: rabbitmq
    port: 5672
    username: guest
    password: guest

  cloud:
    stream:
      bindings:
        input:
          destination: stateChangeTopic
          content-type: application/json
          group: stateChangeGroup
        output:
          destination: stateChangeRspTopic
          content-type: application/json
          group: stateChangeRspGroup

输出日志也位于github中的以下链接中:https://github.com/achintmehta/springclouddemo/blob/master/logs.txt

1 个答案:

答案 0 :(得分:1)

您的应用程序有几处错误

  1. 为什么要在应用程序中注入处理器?我的意思是说,这样做的全部目的是向框架发出信号,以创建必要的绑定,以桥接/映射与远程目的地(Kafka,Rabbit等)的本地频道。这意味着,当您直接向input通道发送消息时,您将完全绕过spring-cloud-stream框架及其所有功能,包括错误处理,消息转换,重试等。指出您根本就没有使用spring-cloud-stream。引发异常时,该异常将传播回原始调用方。在spring-cloud-stream的情况下,原始调用者是消息侦听容器,它捕获异常,重试然后经过error handling routine,包括发送到错误通道。在您的情况下,原始调用者是您通过source.input().send(...),而不是框架。

  2. 此处的签名是错误的:@ServiceActivator(inputChannel="errorChannel") public ErrorMessage onError(ErrorMessage message)。通过返回除void之外的任何内容,您有什么期望?错误消息会去哪里?