springamqp 动态 Exchange Queue Failed to check/redeclare auto-delete queue(s).

ERROR [czx] 2023-02-04 12:15:58.188 [SimpleAsyncTaskExecutor-1] org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer:1618 - Failed to check/redeclare auto-delete queue(s).     
java.lang.NullPointerException: null
	at org.springframework.amqp.rabbit.core.RabbitAdmin.initialize(RabbitAdmin.java:496)
	at org.springframework.amqp.rabbit.core.RabbitAdmin.lambda$null$9(RabbitAdmin.java:453)
	at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287)
	at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:164)
	at org.springframework.amqp.rabbit.core.RabbitAdmin.lambda$afterPropertiesSet$10(RabbitAdmin.java:452)
	at org.springframework.amqp.rabbit.connection.CompositeConnectionListener.onCreate(CompositeConnectionListener.java:36)
	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:634)
	at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:240)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1816)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1790)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1771)
	at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueProperties(RabbitAdmin.java:345)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.redeclareElementsIfNecessary(AbstractMessageListenerContainer.java:1604)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:995)
	at java.lang.Thread.run(Thread.java:745)
WARN  [czx] 2023-02-04 12:15:58.268 [SimpleAsyncTaskExecutor-1] org.springframework.amqp.rabbit.listener.BlockingQueueConsumer:690 - Failed to declare queue: hallQueues     
WARN  [czx] 2023-02-04 12:15:58.270 [SimpleAsyncTaskExecutor-1] org.springframework.amqp.rabbit.listener.BlockingQueueConsumer:595 - Queue declaration failed; retries left=3     
org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[hallQueues]
	at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:696)
	at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:586)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:996)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: null
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:126)
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:122)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:144)
	at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:1006)
	at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:52)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:1032)
	at com.sun.proxy.$Proxy212.queueDeclarePassive(Unknown Source)
	at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:675)
	... 3 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'hallQueues' in vhost '/', class-id=50, method-id=10)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:494)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:288)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:138)
	... 12 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'hallQueues' in vhost '/', class-id=50, method-id=10)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:516)
	at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:346)
	at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:178)
	at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:111)
	at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:670)
	at com.rabbitmq.client.impl.AMQConnection.access$300(AMQConnection.java:48)
	at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:597)
	... 1 common frames omitted

表现异常如上。

问题是 Exchange Queue 创建未成功,前提配置一切正常。

动态创建交换机、队列代码参考:springboot 整合RabbitMQ yml配置文件配置交换机 队列信息 - 官萧何 - 博客园

在 spring-boot-starter-parent 2.0.1~2.0.6 都有以上异常错误,怀疑过rabbitma 版本、依赖冲突等诸多错误,在 org.springframework.amqp.rabbit.core.RabbitAdmin.initialize 中debug 找到问题:

 

Collection<Collection> collections = this.declareCollections ? this.applicationContext.getBeansOfType(Collection.class, false, false).values() : Collections.emptyList(); 未拿到对象。
 public void initialize() {
        if (this.applicationContext == null) {
            this.logger.debug("no ApplicationContext has been set, cannot auto-declare Exchanges, Queues, and Bindings");
        } else {
            this.logger.debug("Initializing declarations");
            Collection<Exchange> contextExchanges = new LinkedList(this.applicationContext.getBeansOfType(Exchange.class).values());
            Collection<Queue> contextQueues = new LinkedList(this.applicationContext.getBeansOfType(Queue.class).values());
            Collection<Binding> contextBindings = new LinkedList(this.applicationContext.getBeansOfType(Binding.class).values());
            Collection<Collection> collections = this.declareCollections ? this.applicationContext.getBeansOfType(Collection.class, false, false).values() : Collections.emptyList();
            Iterator var5 = ((Collection)collections).iterator();

解决方法:注入bean 时一定返回交换机对象

 @Bean("createExchange")
    public List<Exchange> createExchange() {
        if (rabbitMqProperties == null) {
            return null;
        }
        List<ExchangeProperties> exchanges = rabbitMqProperties.getExchanges();
        List<Exchange> exchangeList = new ArrayList<>();
        if (CollUtil.isNotEmpty(exchanges)) {
            exchanges.forEach(e -> {
                // 声明交换机
                Exchange exchange = null;
                switch (e.getType()) {
                    case DIRECT:
                        exchange = new DirectExchange(e.getName());
                        break;
                    case TOPIC:
                        exchange = new TopicExchange(e.getName());
                        break;
                    case HEADERS:
                        exchange = new HeadersExchange(e.getName());
                        break;
                    case FANOUT:
                        exchange = new FanoutExchange(e.getName());
                        break;
                    case CUSTOM:
                        exchange = new CustomExchange(e.getName(), e.getCustomType(), true, false, e.getArguments());
                        break;
                    default:
                        break;
                }
                // 将交换机注册到spring bean工厂 让spring实现交换机的管理
                if (exchange != null) {
                    beanFactory.registerSingleton(e.getName(), exchange);
                    exchangeList.add(exchange);
                }
            });
        }
        return exchangeList;// 就是这个返回解决了问题
    }

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值