Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 无法订阅全局错误频道_Spring_Spring Integration_Spring Cloud Stream - Fatal编程技术网

Spring 无法订阅全局错误频道

Spring 无法订阅全局错误频道,spring,spring-integration,spring-cloud-stream,Spring,Spring Integration,Spring Cloud Stream,我有两个应用程序使用SpringCloudStream和rabbitmq绑定器相互抛出消息。我无法订阅全局或专用错误通道。我确信我错过了一次对一位春天的神的祈祷 我试图将代码简化为以下内容。(代码也可在上获得) 在下面的代码中,我试图向输入通道发送一条消息,并在输出通道上返回一条消息。输入通道的流侦听器抛出一个异常,我看到logHandler正在打印该异常,但没有调用我注册的错误端点 public static void main(String[] args) { Spr

我有两个应用程序使用SpringCloudStream和rabbitmq绑定器相互抛出消息。我无法订阅全局或专用错误通道。我确信我错过了一次对一位春天的神的祈祷

我试图将代码简化为以下内容。(代码也可在上获得)

在下面的代码中,我试图向输入通道发送一条消息,并在输出通道上返回一条消息。输入通道的流侦听器抛出一个异常,我看到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);
    }





输出日志也位于github的以下链接中:

应用程序几乎没有问题

  • 为什么要在应用程序中注入处理器?我的意思是,它的全部目的是向框架发送信号,以创建必要的绑定,将本地通道桥接/映射到远程目的地(Kafka、Rabbit等)。这意味着,当您直接将消息发送到
    input
    通道时,您完全绕过了spring cloud stream框架及其所有功能,包括错误处理、消息转换、重试等。基本上,此时您根本不使用spring cloud stream。当抛出异常时,异常会传播回原始调用方。在SpringCloudStream的情况下,原始调用者是消息侦听容器,它捕获异常,进行重试,然后执行包括发送到错误通道在内的所有操作。在您的情况下,最初的调用者是您通过
    source.input().send(…)
    ,而不是框架

  • 此处的签名错误:
    @ServiceActivator(inputChannel=“errorChannel”)public ErrorMessage onError(ErrorMessage message)
    。通过返回除
    void
    之外的任何内容,您的期望是什么?错误信息会发到哪里


  • 嗨,奥列格,谢谢你的回复。1.您是对的,我在示例代码中使用通道的方式是不正确的。我试图将另外两个应用程序的代码简化为一个演示代码。显然,在这种情况下简化意味着用更少的代码行添加更多的bug。2.感谢您指出onError的类型不正确。一旦我将此函数的类型修改为返回void,我就能够处理全局通道上的错误消息。
     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