RabbitTemplate 连接到 RabbitMQ:获取 - NOT_FOUND - 无队列

Posted

技术标签:

【中文标题】RabbitTemplate 连接到 RabbitMQ:获取 - NOT_FOUND - 无队列【英文标题】:RabbitTemplate to connect to RabbitMQ : getting - NOT_FOUND - no queue 【发布时间】:2017-01-20 15:57:25 【问题描述】:

我是 Spring 新手,正在开发基于云的应用程序并尝试使用 RabbitTemplate 和 RabbitMQ。

我能够将数据存储到队列中。

rabbitTemplate.convertAndSend(QUEUE_NAME, msg);

但是当我使用从同一个队列接收数据时

rabbitTemplate.receiveAndConvert(QUEUE_NAME)

我遇到了异常:

ERR 原因:java.io.IOException 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:106) 的 ERR 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:102) 的 ERR 2016-09-13T11:15:21.38+0530 [App/0] ERR 在 com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:124) 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.ChannelN.basicGet(ChannelN.java:985) 的错误 2016-09-13T11:15:21.38+0530 [App/0] 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)的错误 2016-09-13T11:15:21.38+0530 [App/0] 在 sun.reflect.NativeMethodAccessorImpl.invoke 的错误(NativeMethodAccessorImpl.java:62) 2016-09-13T11:15:21.38+0530 [App/0] 在 sun.reflect.DelegatingMethodAccessorImpl.invoke 出现错误(DelegatingMethodAccessorImpl.java:43) 2016-09-13T11:15:21.38+0530 [App/0] java.lang.reflect.Method.invoke (Method.java:498) 的错误 2016-09-13T11:15:21.38+0530 [App/0] ERR at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:625) 2016-09-13T11:15:21.38+0530 [App/0] com.sun.proxy.$Proxy55.basicGet 的 ERR(未知来源) 2016-09-13T11:15:21.38+0530 [App/0] ERR at org.springframework.amqp.rabbit.core.RabbitTemplate$4.doInRabbit(RabbitTemplate.java:650) 2016-09-13T11:15:21.38+0530 [App/0] ERR at org.springframework.amqp.rabbit.core.RabbitTemplate$4.doInRabbit(RabbitTemplate.java:646) 2016-09-13T11:15:21.38+0530 [App/0] ERR 在 org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1045) 2016-09-13T11:15:21.38+0530 [App/0] ERR ... 50 更多 2016-09-13T11:15:21.38+0530 [App/0] ERR 原因:com.rabbitmq.client.ShutdownSignalException:通道错误;协议方法:#method(reply-code=404,reply-text=NOT_FOUND - vhost '9cc1b4db-636e-4251-bb68-c7ed7f3be1d3' 中没有队列 'testqueue',class-id=60,method-id=70) 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:67) 处的错误 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:33) 的错误 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply (AMQChannel.java:343) 的 ERR 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:216) 的 ERR 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:118) 的 ERR 2016-09-13T11:15:21.38+0530 [App/0] ERR ... 60 更多 2016-09-13T11:15:21.38+0530 [App/0] ERR 原因:com.rabbitmq.client.ShutdownSignalException:通道错误;协议方法:#method(reply-code=404,reply-text=NOT_FOUND - vhost '9cc1b4db-636e-4251-bb68-c7ed7f3be1d3' 中没有队列 'testqueue',class-id=60,method-id=70) 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.ChannelN.asyncShutdown (ChannelN.java:478) 的 ERR 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.ChannelN.processAsync 的错误(ChannelN.java:315) 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand (AMQChannel.java:144) 的 ERR 2016-09-13T11:15:21.38+0530 [App/0] com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:91) 的 ERR 2016-09-13T11:15:21.38+0530 [App/0] ERR 在 com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:552)

我的代码:

@Configuration
@Profile("cloud")
public class RabbitConfig extends AbstractCloudConfig 

@Bean
public RabbitTemplate rabbitTemplate()
    CachingConnectionFactory cachingConnectionFactory = (CachingConnectionFactory)connectionFactory().rabbitConnectionFactory();

    cachingConnectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL);

    RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);

    return rabbitTemplate;
    

我的控制器:

@RestController
@RequestMapping("mq")
public class MainController 

@Autowired
private RabbitTemplate rabbitTemplate;

private static final String QUEUE_NAME = "testqueue";

@RequestMapping(value = "/putinq/msg",method = RequestMethod.PUT)
public String storeMessage(@PathVariable("msg") String msg)
    String result = "";

    rabbitTemplate.setQueue(QUEUE_NAME);
    try 
        rabbitTemplate.convertAndSend(QUEUE_NAME, msg); // no exception
        Thread.sleep(3000);
        Object object = rabbitTemplate.receiveAndConvert(QUEUE_NAME); // getting exception here
          System.out.println("Received: "+object);
        result = "success";
    catch(Exception ex)
        ex.printStackTrace();
    

    return result;


更新的 RabbitConfig.java

@Configuration
@Profile("cloud")
public class RabbitConfig extends AbstractCloudConfig 

private static final String QUEUE_NAME = "testqueue";

@Bean
public RabbitTemplate rabbitTemplate()
    CachingConnectionFactory cachingConnectionFactory = (CachingConnectionFactory)(connectionFactory().rabbitConnectionFactory());
    System.out.println("------------------------ Rabbit mq template: " + cachingConnectionFactory.getCacheMode());
    System.out.println("------------------------ cachingConnectionFactory.toString(): " + cachingConnectionFactory.toString());
    cachingConnectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL);
    cachingConnectionFactory.setChannelCacheSize(25);
    System.out.println("----------after set-------------- Rabbit mq template: " + cachingConnectionFactory.getCacheMode());
    System.out.println("------------------------ cachingConnectionFactory.toString(): " + cachingConnectionFactory.getChannelCacheSize());
    RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);

    System.out.println("------------------------ Rabbit mq template: " + rabbitTemplate);
    return rabbitTemplate;


@Bean
public Queue myQueue() 
    System.out.println("--------------@@---------- creating queue: ");
    final boolean isDurable = true;
    final boolean isExclusive = false;
    final boolean autoDelete = false;
    return new Queue(QUEUE_NAME, isDurable, isExclusive, autoDelete);




我尝试在互联网上搜索此问题,但仍然无法解决问题,长期与此异常作斗争,感谢任何帮助。

找到解决方案!

CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
    cachingConnectionFactory.setUsername("");
    cachingConnectionFactory.setPassword("");
    cachingConnectionFactory.setVirtualHost("");
    cachingConnectionFactory.setHost("");
    cachingConnectionFactory.setPort(1);
    cachingConnectionFactory.setRequestedHeartBeat(30);
    cachingConnectionFactory.setConnectionTimeout(30000);

    RabbitAdmin admin = new RabbitAdmin(cachingConnectionFactory());
    Queue queue = new Queue(QUEUE_NAME);
    admin.declareQueue(queue);
    TopicExchange exchange = new TopicExchange(EXCHANGE_NAME);
    admin.declareExchange(exchange);   admin.declareBinding(BindingBuilder.bind(queue).to(exchange).with(QUEUE_NAME));
RabbitTemplate template = new RabbitTemplate(cachingConnectionFactory());

【问题讨论】:

【参考方案1】:

您需要 RabbitAdmin @Bean 来声明队列/绑定 - 它会自动查找这些类型的 bean 并在建立连接时在代理上声明它们。

如果你使用 Spring Boot,它会自动为你注册一个模板和管理员。

【讨论】:

【参考方案2】:

你需要绑定你的队列和exchage,请试试下面这个RabbitmqConfig

@Configuration
public class RabbitmqConfig  
    private static final String QUEUE_NAME = "testqueue";

    @Bean
    Queue queue() 
        return new Queue(QUEUE_NAME, false);
    

    @Bean
    TopicExchange exchange() 
        return new TopicExchange("spring-boot-exchange", true, false);
    

    @Bean
    Binding binding(Queue queue, TopicExchange exchange) 
        return BindingBuilder.bind(queue).to(exchange).with(QUEUE_NAME);
    

【讨论】:

得到同样的错误:ERR 原因:com.rabbitmq.client.ShutdownSignalException:通道错误;协议方法:#method(reply-code=404,reply-text=NOT_FOUND - vhost '9cc1b4db-636e-4251-bb68-c7ed7f3be1d3' 中没有队列 'testqueue',class-id=60,method- id=70) 发送到队列不会出错,但接收会抛出上述异常 @RiteshKaushik 请尝试从您的代码中删除rabbitTemplate.setQueue(QUEUE_NAME); 雅丽萍,做到了,不走运!我不知道为什么它仍然给出这个错误。 @RiteshKaushik 你能去 rabbitmq 管理员检查队列/频道吗?【参考方案3】:

您需要在配置中定义队列本身。

@Bean
public org.springframework.amqp.core.Queue myQueue() 
    final boolean isDurable = true;
    final boolean isExclusive = false;
    final boolean autoDelete = false;
    return new org.springframework.amqp.core.Queue(QUEUE_NAME, isDurable, isExclusive, autoDelete);

【讨论】:

嗨,杰夫,感谢您的回复,我仍然收到同样的错误:原因:com.rabbitmq.client.ShutdownSignalException:通道错误;协议方法:#method(reply-code=404,reply-text=NOT_FOUND - vhost '9cc1b4db-636e-4251-bb68-c7ed7f3be1d3' 中没有队列 'testqueue',class-id=60,method- id=70) 你把它放在你的 RabbitConfig 中并用配置文件云运行它了吗? (-Dspring.profiles.active=cloud 在大多数 IDE 中作为运行参数或 vm 参数) Ya Jeff,我已经粘贴了更新后的 RabbitConfig.java Binding你的QueueExchange了吗? 删除rabbitTemplate()方法会怎样?

以上是关于RabbitTemplate 连接到 RabbitMQ:获取 - NOT_FOUND - 无队列的主要内容,如果未能解决你的问题,请参考以下文章

Windows XP 上的 rabbitmqctl.bat:无法连接到节点 rabbit@MYPCNAME:nodedown

从dockerfile构建的docker容器运行时无法连接到Rabbit MQ实例

rabbit mq 循环依赖报错

RabbitMq 创建消费者

RabbitMQ 集群:无法连接到节点:nodedown

如何使用 spring-rabbit 配置 RabbitMQ 连接?