10-exchangeDeclare和queueDeclare

参考:https://www.jianshu.com/p/ba3fa6071bd6

在使用RMQ的时候有两个非常重要的方法(基于Java客户端实现amqp-client):

  • exchangeDeclare:声明一个交换机。
  • queueDeclare:声明一个队列。

生产者和消费者都可以声明一个交换机或者队列。
如果尝试声明一个已经存在的交换机或者队列,只要声明的参数完全匹配现存的交换机或者队列,RabbitMQ 就可以什么都不做,并成功返回;如果声明的参数不匹配,则会抛出异常。

1 exchangeDeclare

1.1 声明exchange

用于声明一个交换机,函数签名如下:

Exchange.DeclareOk exchangeDeclare(String exchange,
                                   String type,
                                   boolean durable,
                                   boolean autoDelete,
                                   boolean internal,
                                   Map<String, Object> arguments) throws IOException;

参数说明:

  • exchange:指定交换机的名称。
  • type:指定交换机的类型(fanoutdirecttopicheaders)。
  • durable:是否持久化。如果设置为true,则rabbitmq会将exchange信息保存到磁盘,服务器重启后exchange不会丢失。
  • autoDelete:是否自动删除。如果设置为true,则当这个exchange不在被使用的时候,rabbitmq就会将它删除。
    • 自动删除的前提是:至少有一个队列或者交换机与这个交换机绑定,之后所有与这个交换机绑定的队列或者交换机都与之解绑,则这个交换机会被自动删除。 注意不能错误地把这个参数理解为:当与此交换机连接的客户端都断开时,RabbitMQ会自动删除本交换器。
  • internal:是否内置的。如果设置为true,则这个exchange就是一个内置交换机,不能直接通过客户端程序发送消息到这个交换机,只能通过交换机路由交换机的方式。
  • arguments:交换机的一些参数。
  • Exchange.DeclareOk:方法的返回值。客户端声明了一个交换器之后,需要等待服务器的返回(服务器会返回Exchange Declare-Ok这个AMQP命令)。

还存在一个类似的方法,函数签名如下:

void exchangeDeclareNoWait(String exchange,
                           String type,
                           boolean durable,
                           boolean autoDelete,
                           boolean internal,
                           Map<String, Object> arguments) throws IOException;

这个方法不需要等待服务器返回,因此exchange可能还没创建好,我们去使用的时候会报错。所以这个方法不太建议使用!

1.2 检测exchange是否存在

还有一个方法,可以用来检测exchange是否存在,函数签名如下:

Exchange.DeclareOk exchangeDeclarePassive(String name) throws IOException;

如果name指定的exchange存在,函数将会正常返回Exchange.DeclareOk;如果exchange不存在,则会抛出IOException,同时channel将会被关闭。

Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method(reply-code=404, reply-text=NOT_FOUND - no exchange 'my-exchange-name' in vhost '/', class-id=40, method-id=10)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:522)
	...

1.3 删除exchange

同时,还有一个方法用来删除已经存在的exchange,函数签名如下:

Exchange.DeleteOk exchangeDelete(String exchange) throws IOException;

Exchange.DeleteOk exchangeDelete(String exchange, boolean ifUnused) throws IOException;

void exchangeDeleteNoWait(String exchange, boolean ifUnused) throws IOException;

参数说明:

  • exchange:指定要删除的exchange的名称。
  • ifUnused:是否在不再被使用的时候删除。如果设置为true,则只有在exchange不再被使用的时候才会被删除。

2 queueDeclare

2.1 声明queue

声明一个队列,函数签名如下:

Queue.DeclareOk queueDeclare() throws IOException;

Queue.DeclareOk queueDeclare(String queue,
                             boolean durable,
                             boolean exclusive,
                             boolean autoDelete,
                             Map<String, Object> arguments) throws IOException;

不带任何参数的queueDeclare()方法,默认会创建一个由rabbitmq命名的(形如amq.gen-LhQzlgv3GhDOv8PIDabOXA)、排他的、自动删除的、非持久化的队列。

参数说明:

  • queue:指定队列名称。

  • durable:是否持久化。如果设置为true,队列信息将会保存到磁盘中,rabbitmq重启之后队列不会丢失。

  • exclusive:是否排他。如果设置为true,表示这个队列是一个排他队列,则只会对首次声明它的连接可见,并在连接断开的时候自动删除。

    • 排他队列是基于连接(Connection)可见的,同一个连接的不同通道(Channel)是可以同时访问同一个连接申明的排他队列。
    • 如果一个连接已经声明了一个排他队列,那么其他的连接就不能再建立同名的排他队列了。
    • 即使这个排他队列被设置为持久化的,一旦连接关闭,这个排他队列还是会被自动删除的。
  • autoDelete:是否自动删除。如果设置为true,则当队列不在被使用的时候会被自动删除。

    • 自动删除的前提是:至少有一个消费者连接到了这个队列,之后所有与这个队列连接的消费者都断开时才会自动删除。 不能把这个参数错误地理解为:当连接到此队列的所有客户端断开时这个队列自动删除,因为如果这个队列是生产者客户端创建的,或者从来没有消费者客户端与这个队列连接时,都不会自动删除这个队列。
  • arguments:设置队列的一些参数。

注意:

生产者和消费者都能够使用queueDeclare来声明一个队列,但是如果消费者在一个通道(Channel)上已经订阅了一个队列,那么就不能再在这个通道上声明另一个队列了。必须先取消订阅,然后将通道置为“传输" 模式,之后才能声明队列。

同样,还存在一个类似的函数:

void queueDeclareNoWait(String queue,
                        boolean durable,
                        boolean exclusive,
                        boolean autoDelete,
                        Map<String, Object> arguments) throws IOException;

该函数不会等待服务器返回申明队列成功的返回值,不建议使用。

2.2 检测queue是否存在

同样,有一个方法用来检测queue是否存在,函数签名如下:

Queue.DeclareOk queueDeclarePassive(String queue) throws IOException;

如果queue指定的队列存在,则返回Queue.DeclareOk;如果队列不存在,则会抛出IOException,同时channel将会被关闭。

2.3 删除queue

同样也有删除队列的方法:

Queue.DeleteOk queueDelete(String queue) throws IOException;

Queue.DeleteOk queueDelete(String queue,
                           boolean ifUnused,
                           boolean ifEmpty) throws IOException;

void queueDeleteNoWait(String queue,
                       boolean ifUnused,
                       boolean ifEmpty) throws IOException;

参数说明:

  • queue:指定要删除的队列的名称。
  • ifUnused:是否在不再被使用的时候删除。如果设置为true,则只有在queue不再被使用的时候才会被删除。
  • ifEmpty:是否在队列为空的时候删除。如果设置为true,则只有当队列中没有消息的时候才能够被删除。

2.4 清空queue

还有一个方法用于清空队列中的内容,而不删除队列。函数签名如下:

Queue.PurgeOk queuePurge(String queue) throws IOException;

你可能感兴趣的:(RabbitMQ)