栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

RabbitMQ ReturnCallback没有执行

RabbitMQ ReturnCallback没有执行

项目场景:

测试RabbitMQ 消息确认机制中的ReturnCallback。已经按照要求做了如下配置:

application.yml中配置:

spring:
  rabbitmq:
    host: 远程ip
    port: 5672
    virtual-host: /xzk
    username: ******
    password: ****** 
    publisher-/confirm/i-type: correlated
    publisher-returns: true
    template:
      mandatory: true

问题描述:

使用Junit单元测试工具进行测试。
使用RabbitTemplate进行错误的消息发送后(具体是指发送到错误的routing key),没有成功执行ReturnCallback。但是使用调试模式执行的时候,却能正常执行ReturnCallback。

package com.kkb.hd;

import com.kkb.hd.config.RabbitMQConfig;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.PropertySource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;




@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerApplicationTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Test
    public void testReturn(){
        rabbitTemplate.setMandatory(true); //此处和spring.rabbitmq.template.mandatory=true效果一样
        rabbitTemplate.setReturnsCallback(returnedMessage -> {
            System.out.println("return执行了...");
            String exchange = returnedMessage.getExchange();
            String routingKey = returnedMessage.getRoutingKey();
            //String queue = returnedMessage.getMessage().getMessageProperties().getConsumerQueue();
            System.out.println("消息从" + exchange + "到路由key为" + routingKey);
            System.out.println("消息为:" + new String(returnedMessage.getMessage().getBody(), StandardCharsets.UTF_8));
        });

        //测试发送到一个不存在的routing key
        rabbitTemplate.convertAndSend("spring-direct-exchange", "kkkk", "新增商品" );
    }

}

原因分析:

ReturnCallback是在exchange->queue过程中发送失败才执行的。个人猜测exchange向queue发送消息与主线程是异步执行的,即主线程只要向exchange发送了消息就不管了,主线程继续后续的操作,而exchange在另一个线程中向queue发送消息。因此主线程提前结束,自然就执行不到exchange线程发送错误后的回调函数。


解决方案:

检查有没有配置rabbitTemplate.setMandatory(true)检查是否在application.yml中配置:spring.rabbitmq.publisher-returns=true(使用yaml的语法格式)以上确认无误后,在主线程最后加一段延时程序:

//测试发送到一个不存在的routing key
rabbitTemplate.convertAndSend("spring-direct-exchange", "kkkk", "新增商品" );
try {
            TimeUnit.SECONDS.sleep(1L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/748170.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号