Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.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
Java 使spring amqp使用者停止使用指定类型异常的消息_Java_Spring_Rabbitmq_Spring Amqp_Spring Rabbit - Fatal编程技术网

Java 使spring amqp使用者停止使用指定类型异常的消息

Java 使spring amqp使用者停止使用指定类型异常的消息,java,spring,rabbitmq,spring-amqp,spring-rabbit,Java,Spring,Rabbitmq,Spring Amqp,Spring Rabbit,我正在使用spring amqp和rabbitmq 我有一个用例,其中我的消费者依赖另一个可能有停机时间的system-X。我想要的是用下面的方式处理当X下降时得到的异常- 在XDownException上,我想停止处理队列中的消息,这样我就不会在停机期间丢失这些消息,并继续对消息重新排队,直到我停止获取XDownException。这样,我确信当X关闭时我不会丢失任何消息,然后在X打开时自动恢复 先进先出是必须的。在处理消息时,侦听器将抛出XDownException。侦听器现在不支持事务,但

我正在使用spring amqp和rabbitmq

我有一个用例,其中我的消费者依赖另一个可能有停机时间的system-X。我想要的是用下面的方式处理当X下降时得到的异常- 在XDownException上,我想停止处理队列中的消息,这样我就不会在停机期间丢失这些消息,并继续对消息重新排队,直到我停止获取XDownException。这样,我确信当X关闭时我不会丢失任何消息,然后在X打开时自动恢复

先进先出是必须的。在处理消息时,侦听器将抛出XDownException。侦听器现在不支持事务,但是如果这样有帮助的话,我们可以让它支持事务。 但是我不想对每一种异常都这样做。。。 有没有一种方法可以用spring amqp实现这一点


还有,有没有比这种方法更好的方法来实现这一点?我没有出现X的事件。

FIFO要求在容器设置中不能有多个并发使用者。假设采用这种设置,您将在POJO方法中逐个接收每条消息。除非完全处理此消息,否则无法传递下一条消息

下面是您所描述的用例在本例中应该采用的策略

  • 确保将容器上的预取大小设置为1,并手动确认模式。详情请浏览
  • 您的设置应该如下所示
  • 
    
    请调整以上大纲,以最适合您的需要。以下链接将为您提供更多有用信息


  • 问题1:假设您将消息驱动的POJO与spring侦听器容器一起使用,您是否希望在侦听器中处理接收到的消息时出现XDownException(以及其他可能的异常)?问题2:您的侦听器是否知道事务?问题3:FIFO(换句话说,保证顺序交付)是您必须满足的要求吗?用例的解决方案将取决于这些问题的答案。请使用其他输入更新您的问题,以便其他人提供帮助。使用这些详细信息更新问题谢谢您的回答。。。我看到我们正在重试进程消息,直到X再次备份。添加延迟有助于优化重试次数。我已经投了赞成票,但我只是在想是否有更好的方法来解决这个问题。有更好的方法,但严格的FIFO要求使情况变得复杂。由于没有关于X可用性的明确通知,因此重试是确定X是否可用的唯一选项,这一事实使情况更加复杂。如果有一个事件通知X再次启动,那么它也是一个选项。
    public class ExtendedListenerAdapter extends MessageListenerAdapter {
        @Override
        protected Object[] buildListenerArguments(Object extractedMessage, Channel channel, Message message) {
            return new Object[]{extractedMessage, channel, message};
        }
    }
    
    
    public class MyListener {
        public void handleMessage(Object object, Channel channel, Message message) throws IOException {
            try {
                processMessage(Object)
            } catch (XDownException xdex) {
                waitForXAvailability(object);
            } catch (OtherException oex) {
            } finally {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
        }
        
        private processMessage(Object object) /* throws All types of exceptions */ {
            // process the message as usual
        }
        
        private waitForXAvailability(Object object) {
            for (;;) {
                // add delay here, exponetial backoff delay recommend with upper bound
                // also add upper bounds on number of iteration you want to keep, it's infinte now
                try {
                    processMessage(Object);
                    return; // no exception means X is up again
                } catch (XDownException xdex) {
                    // x is down, let the loop continue
                }
            }
        }
    }
    
    @Configuration
    public class ExampleAmqpConfiguration {
    
        @Bean
        public SimpleMessageListenerContainer messageListenerContainer() {
            SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
            container.setConnectionFactory(rabbitConnectionFactory());
            container.setQueueName("some.queue");
            container.setPrefetchCount(1)
            container.setAcknowledgeMode(AcknowledgeMode.MANUAL)
            container.setMessageListener(myAdapter());
            return container;
        }
    
        @Bean
        public ConnectionFactory rabbitConnectionFactory() {
            CachingConnectionFactory connectionFactory =
                new CachingConnectionFactory("localhost");
            connectionFactory.setUsername("guest");
            connectionFactory.setPassword("guest");
            return connectionFactory;
        }
    
        @Bean
        public ExtendedListenerAdapter myAdapter() {
            ExtendedListenerAdapter adapter = new ExtendedListenerAdapter();
            listenerAdapter.setDelegate(myListener())
            return adapter;
        }
        
        @Bean
        public MyListener myListener() {
            return new MyListener();
        }
    }