SpringBoot下RabbitMQ消费消息欲删消息却遇ReplyTo属性异常
解决Spring AMQP ReplyTo属性异常问题
首先咱们先理清这个异常的根源:你的监听器方法返回了message.payload,而Spring AMQP默认会把方法的返回值当作需要回复的消息。这时候它会去两个地方找回复地址:要么消息本身携带了reply-to属性,要么你配置了默认的响应交换机。但你既没在发送消息时设置reply-to,也没配置默认回复交换机,所以就抛出了这个异常。
针对你的三个疑问,逐一解答:
是否需要创建虚拟响应交换机?
完全不需要。你的需求只是消费消息后让它从队列删除,根本不需要回复消息,所以没必要折腾响应交换机。是否需要硬编码不存在的replyTo属性?
也不需要。硬编码反而会增加不必要的复杂度,而且不是解决问题的核心思路。是否需要配置现有TopicExchange或队列?
不需要修改现有的交换机和队列配置,问题出在监听器的处理逻辑上,和它们无关。
具体解决方案
最直接的解决方法是让监听器方法不返回任何内容,把返回类型改成void,这样Spring AMQP就不会尝试发送回复消息了,代码修改如下:
@RabbitListener(queues = "inbound-queue") void onInboundMessage(def message) { try { log.debug("Received inbound message: ${message.messageId} on inbound queue listener", message) } catch (Exception ex) { log.error("Inbound message exception: ${ex.getMessage()}") return; } }
如果你因为某些原因必须保留返回值(虽然你的需求里不需要),也可以通过@SendTo注解指定一个空的回复地址,明确告诉框架不需要发送回复:
@RabbitListener(queues = "inbound-queue") @SendTo("") def onInboundMessage(def message) { try { log.debug("Received inbound message: ${message.messageId} on inbound queue listener", message) } catch (Exception ex) { log.error("Inbound message exception: ${ex.getMessage()}") return; } return message.payload }
不过更推荐第一种方案,因为它完全贴合你“消费后删除消息”的需求,逻辑更清晰简洁。
内容的提问来源于stack exchange,提问作者Mandark
相关产品推荐
相关产品推荐

