1、消费端代码:

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "queue1.pay",durable = "true"),
        exchange = @Exchange(value = "exchange.pay"),
        key = "ali.*"))
public void receive1(String data, Message  message, Channel channel){
    System.out.println("receive1收到消息:"+data);
}

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "queue2.pay",durable = "true"),
        exchange = @Exchange(value = "exchange.pay"),
        key = "wechat.*"))
public void receive2(String data, Message  message, Channel channel){
    System.out.println("receive2收到消息:"+data);
}

2、生产端代码:
 

@Test
void singleSend() {
    rabbitTemplate.convertAndSend("exchange.pay","wechat.pay","Hello World");
}

配置类(消息发送交换机成功或者失败,都会执行confirm方法,主要看返回的ack的值;若消息路由至队列失败,则会执行returnedMessage方法):

@Configuration
public class RabbitmqConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {

    public RabbitmqConfig(RabbitTemplate rabbitTemplate) {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        System.out.println("correlationData:"+correlationData);
        System.out.println("ack:"+b);
        System.out.println("cause:"+s);
    }

    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        System.out.println("returnedMessage:"+returnedMessage);
        System.out.println("returnedMessage.getMessage():"+returnedMessage.getMessage()           );
    }
}

3、问题

生产端发送消息,消费端receive2方法收不到消息,而且mq管理界面,queue2.pay也未收到消息

4、问题定位:

1)消费端监听的队列名称写错;

2)生产端发送的交换机名称或者路由键写错;

3)消费端申明的交换机模式与rountingkey的匹配模式不一致;

4、排查:

1)启动生产端模块,发送消息;

2)启动消费端模块开始监听消息,结果生产的配置类中confirm和returnedMessage方法都执行了,confirm方法中打印ack =“true”,这就说明消息成功发送到了mq,但是returnedMessage方法也收到了信息,说明没有成功路由到对应队列,因为returnedMessage方法一旦执行就说明路由失败

3)在mq管理界面,检查到exchange.pay的type是direct,而在消费端申明交换机的routingkey时,采用的是*这种通配符方式

5、解决:

1)在消费端@Exchange中加上type ="topic" ,表明创建的交换机类型为主题模式,不然默认就是direct;

2)或者在mq管理界面,删除对应交换机,重新创建一个type=topic的exchange.pay

更多推荐