rabbitMQ 问题汇总

2023/10/07 MQ系列 共 22291 字,约 64 分钟
闷骚的程序员

1. java 原生客户端问题总结

在这一篇中,我们将使用java原生客户端,来验证我们的一些猜想。

2. 如果服务器存在了交换机,客户端还可以创建?

不知道大家有没有关心过,之前,我们在编写代码时,生产者或者消费者里面都有创建交换机的代码。
我们通过启动代码,向rabbitMQ服务器中创建了一个交换机。
如果这个交换机是持久化的,那么我们关闭代码,这个交换机依旧在rabbitMQ服务器上存在。
这时候,我们再重新启动代码,相当于我们要重新创建一次交换机。
这时候会发生什么事情?
会报错?
还是会重新创建一个同名的Exchange?
还是说复用rabbitMQ服务器上已经存在的Exchange?
如果我们第二次启动前,更改了这个同名Exchange的属性,比如之前是持久化的,现在改为暂时的,又会出现什么情况?

下来我们测试一下。
rabbitMQ.demo05.RabbitMqConstants

public class RabbitMqConstants {

    // 交换机名称
    public static final String EXCHANGE_NAME = "create_exchange_01";


    // 队列名称
    public static final String QUEUE_NAME = "create_queue_01";


    // 路由键名称
    public static final String ROUTING_KEY_NAME = "create_routing_key_01";
}

rabbitMQ.demo05.ExchangeCreator

package rabbitMQ.demo05;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

// 创建 Exchange
public class ExchangeCreator {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();

        connectionFactory.setHost("127.0.0.1");

        Connection connection = connectionFactory.newConnection();

        Channel channel = connection.createChannel();

        // 创建一个交换机,direct类型,非持久化、非内部交换机、非连接独占、空参数
        channel.exchangeDeclare(RabbitMqConstants.EXCHANGE_NAME, "direct", false, false, false, null);

        channel.close();
        connection.close();
    }
}

通过channel去创建一个名称为 create_exchange_01 的交换机。
运行后观察web端:

发现交换机被成功创建。

我们再次运行上面的程序,发现程序依旧能成功运行。
我们尝试修改下上面Exchange的属性,比如将非持久化改为持久化:

channel.exchangeDeclare(RabbitMqConstants.EXCHANGE_NAME, "direct", true, false, false, null);

然后重新运行:

C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\bin\java.exe "-javaagent:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63244:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\charsets.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\deploy.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\access-bridge-64.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\cldrdata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\dnsns.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jaccess.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jfxrt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\localedata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\nashorn.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunec.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunjce_provider.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunmscapi.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunpkcs11.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\zipfs.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\javaws.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jce.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfr.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfxswt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jsse.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\management-agent.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\plugin.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\resources.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\rt.jar;C:\D\gitsource\zhaoehcode-java\rabbitmq-java\target\classes;C:\D\soft\soft_application\maven\repo\com\rabbitmq\amqp-client\3.6.5\amqp-client-3.6.5.jar rabbitMQ.demo05.ExchangeCreator
Exception in thread "main" java.io.IOException
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105)
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:123)
	at com.rabbitmq.client.impl.ChannelN.exchangeDeclare(ChannelN.java:702)
	at com.rabbitmq.client.impl.ChannelN.exchangeDeclare(ChannelN.java:60)
	at rabbitMQ.demo05.ExchangeCreator.main(ExchangeCreator.java:32)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'durable' for exchange 'create_exchange_01' in vhost '/': received 'true' but current is 'false', class-id=40, method-id=10)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:32)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:360)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:225)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:117)
	... 3 more
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'durable' for exchange 'create_exchange_01' in vhost '/': received 'true' but current is 'false', class-id=40, method-id=10)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:483)
	at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:320)
	at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:143)
	at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:90)
	at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:559)
	at java.lang.Thread.run(Thread.java:745)

我们惊奇的发现,启动报错了。
下面是关键的报错信息:

inequivalent arg 'durable' for exchange 'create_exchange_01' in vhost '/': received 'true' but current is 'false', class-id=40, method-id=10)

翻译下就是:对虚拟机 / 中的交换机 create_exchange_01 而言有一个不等价的参数 durable :接收到的是true,但是最近运行的是 false。

所以说,当我们尝试在rabbitMQ服务器上重复创建同名的交换机时,它底层复用的是服务器上已经存在的交换机。

如果我们的代码修改了Exchange的属性,然后尝试重新创建,这时候就会报错,因为你尝试修改一个服务器上已经存在的交换机属性,这是不被允许的。

3. 如果重复创建同名的Queue呢?

下来我们以同样的方式测试下Queue。
rabbitMQ.demo05.QueueCreator

package rabbitMQ.demo05;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

// 创建队列
public class QueueCreator {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();

        connectionFactory.setHost("127.0.0.1");

        Connection connection = connectionFactory.newConnection();

        Channel channel = connection.createChannel();

        // 创建一个名称为 create_queue_01 的队列,非持久化、非连接独占、非自动阐述、空参数
        channel.queueDeclare(RabbitMqConstants.QUEUE_NAME, false, false, false, null);

        channel.close();
        connection.close();
    }
}

运行程序后,观察web端:

发现队列 create_queue_01 已经被重新创建。
我们重复运行上面的代码,发现正常运行。

当我们修改了上面队列的属性后:

channel.queueDeclare(RabbitMqConstants.QUEUE_NAME, true, false, false, null);

我们将队列的非连接独占,修改为true,重启后报错了。

C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\bin\java.exe "-javaagent:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63607:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\charsets.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\deploy.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\access-bridge-64.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\cldrdata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\dnsns.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jaccess.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jfxrt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\localedata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\nashorn.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunec.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunjce_provider.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunmscapi.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunpkcs11.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\zipfs.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\javaws.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jce.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfr.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfxswt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jsse.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\management-agent.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\plugin.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\resources.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\rt.jar;C:\D\gitsource\zhaoehcode-java\rabbitmq-java\target\classes;C:\D\soft\soft_application\maven\repo\com\rabbitmq\amqp-client\3.6.5\amqp-client-3.6.5.jar rabbitMQ.demo05.QueueCreator
Exception in thread "main" java.io.IOException
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105)
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:123)
	at com.rabbitmq.client.impl.ChannelN.queueDeclare(ChannelN.java:843)
	at com.rabbitmq.client.impl.ChannelN.queueDeclare(ChannelN.java:60)
	at rabbitMQ.demo05.QueueCreator.main(QueueCreator.java:32)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=405, reply-text=RESOURCE_LOCKED - cannot obtain exclusive access to locked queue 'create_queue_01' in vhost '/'. It could be originally declared on another connection or the exclusive property value does not match that of the original declaration., class-id=50, method-id=10)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:32)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:360)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:225)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:117)
	... 3 more
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=405, reply-text=RESOURCE_LOCKED - cannot obtain exclusive access to locked queue 'create_queue_01' in vhost '/'. It could be originally declared on another connection or the exclusive property value does not match that of the original declaration., class-id=50, method-id=10)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:483)
	at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:320)
	at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:143)
	at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:90)
	at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:559)
	at java.lang.Thread.run(Thread.java:745)

重要信息是:

cannot obtain exclusive access to locked queue 'create_queue_01' in vhost '/'. It could be originally declared on another connection or the exclusive property value does not match that of the original declaration., class-id=50, method-id=10)

无法获得对虚拟主机“/”中锁定队列“create_queue_01”的独占访问权限。 它最初可能是在另一个连接上声明的,或者独占属性值与原始声明的不匹配。(class-id=50,method-id=10)
即我们这次尝试启动创建的同名队列的属性和原始的不匹配。
由此可见,对于队列而言,也是相同的原理。

当我们尝试在rabbitMQ服务器上重复创建同名的队列时,它底层复用的是服务器上已经存在的队列。

因此,当我们修改了同名队列的属性值,启动将报错,这是不被允许的。

4. 如果重复创建重复的绑定呢?

rabbitMQ.demo05.BindingCreator

package rabbitMQ.demo05;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class BindingCreator {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();

        connectionFactory.setHost("127.0.0.1");

        Connection connection = connectionFactory.newConnection();

        Channel channel = connection.createChannel();

        // 创建一个binding,将之前创建的queue和exchange通过routing key进行绑定
        channel.queueBind(RabbitMqConstants.QUEUE_NAME, RabbitMqConstants.EXCHANGE_NAME, RabbitMqConstants.ROUTING_KEY_NAME, null);

        channel.close();
        connection.close();
    }
}

运行程序后,观察web端:

发现之前创建的queue和exchange通过routing key成功绑定了。

我们再运行一次,发现代码成功运行,绑定关系也没有发生变化。

我们修改下routing key,然后重新运行:

package rabbitMQ.demo05;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class BindingCreator {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();

        connectionFactory.setHost("127.0.0.1");

        Connection connection = connectionFactory.newConnection();

        Channel channel = connection.createChannel();

        // 创建一个binding,将之前创建的queue和exchange通过routing key进行绑定
        channel.queueBind(RabbitMqConstants.QUEUE_NAME, RabbitMqConstants.EXCHANGE_NAME, RabbitMqConstants.ROUTING_KEY_NAME, null);

        // 搞一个新的routing key去创建绑定关系
        channel.queueBind(RabbitMqConstants.QUEUE_NAME, RabbitMqConstants.EXCHANGE_NAME, "create_routing_key_02", null);

        channel.close();
        connection.close();
    }
}

观察控制台:

发现新的rouging key创建的绑定关系也成功创建了,而且重复的绑定关系也是复用服务器上已有的绑定。

接下来我们在创建一个绑定关系,尝试绑定一个不存在Exchange和存在的Queue.

        // 创建一个binding,将之前创建的queue和exchange通过routing key进行绑定
        channel.queueBind(RabbitMqConstants.QUEUE_NAME, RabbitMqConstants.EXCHANGE_NAME, RabbitMqConstants.ROUTING_KEY_NAME, null);

        // 搞一个新的routing key去创建绑定关系
        channel.queueBind(RabbitMqConstants.QUEUE_NAME, RabbitMqConstants.EXCHANGE_NAME, "create_routing_key_02", null);

        // 创建一个关系,一个不存在Exchange和一个存在的queue
        channel.queueBind(RabbitMqConstants.QUEUE_NAME, "create_exchange_02", "create_routing_key_02", null);

启动发现报错了:

C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\bin\java.exe "-javaagent:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63849:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\charsets.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\deploy.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\access-bridge-64.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\cldrdata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\dnsns.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jaccess.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jfxrt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\localedata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\nashorn.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunec.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunjce_provider.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunmscapi.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunpkcs11.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\zipfs.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\javaws.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jce.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfr.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfxswt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jsse.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\management-agent.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\plugin.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\resources.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\rt.jar;C:\D\gitsource\zhaoehcode-java\rabbitmq-java\target\classes;C:\D\soft\soft_application\maven\repo\com\rabbitmq\amqp-client\3.6.5\amqp-client-3.6.5.jar rabbitMQ.demo05.BindingCreator
Exception in thread "main" java.io.IOException
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105)
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:123)
	at com.rabbitmq.client.impl.ChannelN.queueBind(ChannelN.java:944)
	at com.rabbitmq.client.impl.ChannelN.queueBind(ChannelN.java:60)
	at rabbitMQ.demo05.BindingCreator.main(BindingCreator.java:35)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'create_exchange_02' in vhost '/', class-id=50, method-id=20)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:32)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:360)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:225)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:117)
	... 3 more
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'create_exchange_02' in vhost '/', class-id=50, method-id=20)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:483)
	at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:320)
	at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:143)
	at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:90)
	at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:559)
	at java.lang.Thread.run(Thread.java:745)

关键报错信息如下:

no exchange 'create_exchange_02' in vhost '/', class-id=50, method-id=20)

也就是我们创建binding时,要求exchange必须存在,否则报错。

接下来在创建一个绑定关系,去绑定一个存在的Exchange和一个不存在的Queue.

        // 创建一个binding,将之前创建的queue和exchange通过routing key进行绑定
        channel.queueBind(RabbitMqConstants.QUEUE_NAME, RabbitMqConstants.EXCHANGE_NAME, RabbitMqConstants.ROUTING_KEY_NAME, null);

        // 搞一个新的routing key去创建绑定关系
        channel.queueBind(RabbitMqConstants.QUEUE_NAME, RabbitMqConstants.EXCHANGE_NAME, "create_routing_key_02", null);

        // 创建一个关系,一个不存在Exchange和一个存在的queue
//        channel.queueBind(RabbitMqConstants.QUEUE_NAME, "create_exchange_02", "create_routing_key_02", null);

        // 创建一个关系,一个存在的Exchange和一个不存在的Queue
        channel.queueBind("create_queue_02", RabbitMqConstants.EXCHANGE_NAME, "create_routing_key_02", null);

启动发现同样报错:

C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\bin\java.exe "-javaagent:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63898:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\charsets.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\deploy.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\access-bridge-64.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\cldrdata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\dnsns.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jaccess.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jfxrt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\localedata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\nashorn.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunec.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunjce_provider.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunmscapi.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunpkcs11.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\zipfs.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\javaws.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jce.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfr.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfxswt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jsse.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\management-agent.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\plugin.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\resources.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\rt.jar;C:\D\gitsource\zhaoehcode-java\rabbitmq-java\target\classes;C:\D\soft\soft_application\maven\repo\com\rabbitmq\amqp-client\3.6.5\amqp-client-3.6.5.jar rabbitMQ.demo05.BindingCreator
Exception in thread "main" java.io.IOException
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105)
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:123)
	at com.rabbitmq.client.impl.ChannelN.queueBind(ChannelN.java:944)
	at com.rabbitmq.client.impl.ChannelN.queueBind(ChannelN.java:60)
	at rabbitMQ.demo05.BindingCreator.main(BindingCreator.java:38)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'create_queue_02' in vhost '/', class-id=50, method-id=20)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:32)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:360)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:225)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:117)
	... 3 more
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'create_queue_02' in vhost '/', class-id=50, method-id=20)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:483)
	at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:320)
	at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:143)
	at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:90)
	at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:559)
	at java.lang.Thread.run(Thread.java:745)

关键报错信息如下:

no queue 'create_queue_02' in vhost '/', class-id=50, method-id=20)

即不存在这个Queue。

5. 总结同名Exchange,同名Queue,重复Binding的问题

1.通过channel对象就可以创建Exchange、Queue、Binding,而不一定非得发送消息才创建。
2.重复创建同名的Exchange,实际上是复用rabbitMQ服务器上已经存在的Exchange,因此不能够更改Exchange的属性值,否则报错。
3.重复创建同名的Queue,实际上也是复用rabbitMQ服务器上已经存在的Queue,因此不能更改Queue的属性值,否则报错。
4.重复创建Binding,要求Exchange和Queue必须已经存在,否则创建Binding失败。当两者存在的时候,可以使用同一个Routing key反复创建Binding,这时候复用的是服务器上已经存在的Binding;也可以修改为新的Routing key去创建一个新的Binding,这时候相当于新创建了一个绑定关系。

文档信息

Search

    Table of Contents