java - RabbitHandler:如何正确捕获“ListenerExecutionFailedException:侦听器方法'不匹配'抛出异常”并继续工作
问题描述
对于一个应用程序,我正在使用 Spring Boot 和 RabbitMQ 进行一些测试。我设置了一个非常简单的 Sender - Receiver 应用程序: Sender:
public class Tut1Sender
{
private final Gson gson = new Gson();
@Autowired
private RabbitTemplate template;
@Autowired
private Queue queue;
public static int count = 1;
@Scheduled(fixedDelay = 1000, initialDelay = 500)
public void send() throws InterruptedException
{
String message = "Hello World! "+" Nr. "+count;
MessageObject mo = new MessageObject(message);
String toJson = gson.toJson(mo);
this.template.convertAndSend(queue.getName(), toJson);
System.out.println(" [x] Sent '" + toJson + "'");
Thread.sleep(5);
count++;
}
}
这部分工作得很好,并用消息填充我的队列。
这是我的接收器:
@RabbitListener(queues = "hello")
public class Tut1Receiver
{
private final Gson gson = new Gson();
@RabbitHandler
public void receive(String in) throws InterruptedException
{
System.out.println("Received Raw: " + in);
MessageObject fromJson = gson.fromJson(in, MessageObject.class);
System.out.println("Received Message '" + fromJson + "'");
int nextInt = ThreadLocalRandom.current().nextInt(1000, 5000);
System.out.println("Sleep for " + nextInt + " ms");
Thread.sleep(nextInt);
}
}
发送者创建的消息由接收者正确处理。我得到了一个很好的输出,消息被确认并从队列中删除。
然后我通过 RabbitMQ 的 Web-GUI 将消息直接放入队列中。
发件人获取此消息。我可以这样说是因为我创建的消息从状态“Ready”切换到“Unacked”(如 Web-GUI 中所示)发件人没有给我任何输出。
然后我配置了ContainerFactory:
@Profile("receiver")
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
SimpleRabbitListenerContainerFactoryConfigurer configurer,
ConnectionFactory connectionFactory)
{
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setErrorHandler(e -> {
System.out.println("Error: "+e);
System.out.println("Raw: "+((ListenerExecutionFailedException) e).getFailedMessage().toString());
});
return factory;
}
现在我收到以下错误(在无限循环中)
Error: org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener method 'no match' threw exception
Raw: (Body:'[B@53452feb(byte[11])' MessageProperties [headers={content_type=text/plain, content_encoding=UTF-8}, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, redelivered=true, receivedExchange=, receivedRoutingKey=hello, deliveryTag=1, consumerTag=NOT_SET, consumerQueue=hello])
我该如何处理这个错误?发件人应该只显示错误,确认消息并继续处理下一条消息。
一般来说,处理错误消息的正确方法是什么?
解决方案
对于破碎的消息,消费者可以reject
或deliver
该消息。如果您确定任何其他消费者无法处理损坏的消息,您应该告诉代理丢弃该消息或将其传递到死信交换。
从spring amqp 的官方文档中,我发现:
另一种选择是将容器的rejectRequeued 属性设置为false。这会导致丢弃所有失败的消息。当使用 RabbitMQ 2.8.x 或更高版本时,这也有助于将消息传递到死信交换。
或者,您可以抛出 AmqpRejectAndDontRequeueException;这可以防止消息重新排队,无论 rejectRequeued 属性的设置如何。
推荐阅读
- ruby-on-rails - 如何在联系表单中添加验证?
- ios - 按标准阻止呼叫 (CallKit)
- javascript - reactjs-popup 没有正确改变状态
- java - 来自一个队列的多个侦听器 RabbitMQ Spring
- delphi - SetThreadDesktop:ERROR_INVALID_HANDLE
- ruby - Ruby 邮件库 如何获取错误报告
- python - Python“如果不存在,那么……”逻辑?
- reporting-services - 封面页上的背景图像在 SSRS 中失真
- numpy - 在python中加速欧几里得距离
- jquery - 如何在第一次单击时选中复选框