You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RabbitMQ消息无限循环与ReplyTo属性缺失异常排查求助

问题分析与解决方案

首先,咱们拆解你遇到的两个核心问题:回复异常引发的无限循环,以及Exchange/Queue路由逻辑混淆。

1. 为什么会抛出Cannot determine ReplyTo message property value异常?

你的@RabbitListener方法返回了ResponseEntity<String>,Spring AMQP会默认把这个返回值当成对消息发送方(Service A)的回复。但这里存在两个问题:

  • Service A发送消息时并没有携带reply-to属性(没告诉RabbitMQ回复消息要发到哪个队列);
  • 你也没在配置里设置默认的回复Exchange;

所以Spring找不到回复的目标,直接抛出异常。更糟的是,这个异常会导致当前消息没有被正确ACK(确认),RabbitMQ会认为这条消息处理失败,不断重新投递它——这就是你看到每分钟2000+条消息的根源:无限循环的消息重投。

解决异常的两种思路:

思路一:不需要给Service A回复,修改方法返回值

如果业务里Service A不需要收到Service B的回复,直接把方法返回类型改成void,不要返回ResponseEntity即可:

@Autowired private RabbitTemplate template;
@RabbitListener(queues=RabbitConfig.QUEUETD)
public void AddSas_Campaign(SasCampaign sasCampaign){
    if (/* 你的判断条件 */) {
        template.convertAndSend(RabbitConfig.EXCHANGE,RabbitConfig.ROUTING_KEY,sasCampaign);
        // 用日志记录操作结果即可,比如 log.info("New line inserted");
    } else {
        // log.info("Campaign Code exists");
    }
}

这样Spring不会尝试回复消息,异常自然消失,消息处理完成后会正常ACK,RabbitMQ也不会重复投递了。

思路二:需要给Service A回复,配置回复机制

如果确实要给Service A回消息,有两种方式:

  • 让Service A在发送消息时,设置reply-to属性,指定回复用的队列;
  • 在RabbitMQ配置里,给RabbitListenerContainerFactory设置默认的回复Exchange和Routing Key:
    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        // 设置默认回复Exchange和Routing Key
        factory.setDefaultReplyExchange("your-reply-exchange");
        factory.setDefaultReplyRoutingKey("your-reply-routing-key");
        return factory;
    }
    

2. 为什么同时启用A→B和B→C会出问题?

大概率是你的路由配置有问题:Service B发送给Service C的消息,又被路由回了自己监听的QUEUETD队列,形成了自循环。

关于Exchange和Queue的关系:

不是必须每个Exchange对应不同的Queue,核心看业务路由需求:

  • Service A→Service B:应该有专属队列(比如queue-a-to-b),绑定到对应Exchange(可以是默认Exchange或自定义),Service B监听这个队列;
  • Service B→Service C:应该用另一个队列(比如queue-b-to-c),绑定到Exchange(可以和上面同一个,只要Routing Key不同,或者用不同Exchange),Service C监听这个队列;
  • 重点:确保Service B发送的消息不会路由回自己监听的队列,否则会自己给自己发消息,触发无限循环。

你可以打开RabbitMQ管理后台,查看Exchange和Queue的绑定关系,确认RabbitConfig.EXCHANGE + RabbitConfig.ROUTING_KEY是不是指向了QUEUETD队列——如果是,调整绑定即可解决。

3. 额外调试建议

  • 用RabbitMQ管理后台查看队列的消息数量和内容,确认是不是重复消息在被重投;
  • 给每条消息加唯一标识(比如在消息头里加message-id),追踪消息流转路径,排查循环来源;
  • 暂时关闭Service B到Service C的发送逻辑,先确认A→B链路正常,再逐步加回B→C逻辑,定位问题点。

内容的提问来源于stack exchange,提问作者rbm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:42:47