Java 使spring amqp使用者停止使用指定类型异常的消息
我正在使用spring amqp和rabbitmq 我有一个用例,其中我的消费者依赖另一个可能有停机时间的system-X。我想要的是用下面的方式处理当X下降时得到的异常- 在XDownException上,我想停止处理队列中的消息,这样我就不会在停机期间丢失这些消息,并继续对消息重新排队,直到我停止获取XDownException。这样,我确信当X关闭时我不会丢失任何消息,然后在X打开时自动恢复 先进先出是必须的。在处理消息时,侦听器将抛出XDownException。侦听器现在不支持事务,但是如果这样有帮助的话,我们可以让它支持事务。 但是我不想对每一种异常都这样做。。。 有没有一种方法可以用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。侦听器现在不支持事务,但
还有,有没有比这种方法更好的方法来实现这一点?我没有出现X的事件。FIFO要求在容器设置中不能有多个并发使用者。假设采用这种设置,您将在POJO方法中逐个接收每条消息。除非完全处理此消息,否则无法传递下一条消息 下面是您所描述的用例在本例中应该采用的策略
请调整以上大纲,以最适合您的需要。以下链接将为您提供更多有用信息
问题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();
}
}