参考:https://www.jianshu.com/p/ba3fa6071bd6
在使用RMQ
的时候有两个非常重要的方法(基于Java客户端实现amqp-client
):
exchangeDeclare
:声明一个交换机。queueDeclare
:声明一个队列。生产者和消费者都可以声明一个交换机或者队列。
如果尝试声明一个已经存在的交换机或者队列,只要声明的参数完全匹配现存的交换机或者队列,RabbitMQ 就可以什么都不做,并成功返回;如果声明的参数不匹配,则会抛出异常。
用于声明一个交换机,函数签名如下:
Exchange.DeclareOk exchangeDeclare(String exchange,
String type,
boolean durable,
boolean autoDelete,
boolean internal,
Map<String, Object> arguments) throws IOException;
参数说明:
exchange
:指定交换机的名称。type
:指定交换机的类型(fanout
、direct
、topic
、headers
)。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
可能还没创建好,我们去使用的时候会报错。所以这个方法不太建议使用!
还有一个方法,可以用来检测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)
...
同时,还有一个方法用来删除已经存在的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
不再被使用的时候才会被删除。声明一个队列,函数签名如下:
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;
该函数不会等待服务器返回申明队列成功的返回值,不建议使用。
同样,有一个方法用来检测queue
是否存在,函数签名如下:
Queue.DeclareOk queueDeclarePassive(String queue) throws IOException;
如果queue
指定的队列存在,则返回Queue.DeclareOk
;如果队列不存在,则会抛出IOException
,同时channel
将会被关闭。
同样也有删除队列的方法:
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
,则只有当队列中没有消息的时候才能够被删除。queue
还有一个方法用于清空队列中的内容,而不删除队列。函数签名如下:
Queue.PurgeOk queuePurge(String queue) throws IOException;