本章是对交换机章节中使用到的有关交换机、队列、绑定等API的总结记录。
交换机
/*
* 声明交换机
* @param1 exchange 交换机名称
* @param2 type 交换机类型
* @param3 durable 是否持久化
* @param4 autoDelete 是否自动删除
* @param5 internal 当前Exchange是否用于RabbitMQ内部使用,默认false
* @param6 arguments 扩展参数,用户扩展AMQP定制化协议
*
* @return AMQP.Exchange.DeclareOk 用来标识成功声明一个交换机
* 打印信息: #method<exchange.declare-ok>()
*/
AMQP.Exchange.DeclareOk declareOk = channel.exchangeDeclare("fanout_exchange",
BuiltinExchangeType.FANOUT, false, true, false, null);
上面声明交换机的方法,是有多个重载方法的,这些重载的方法都是由上面的这个方法种缺省了某些参数构成的。
声明方法参数介绍
- exchange 交换机名称。
- type 交换机类型,常用类型有fanout(扇出),direct(直接),topic(主题),headers(标题)。
- durable 是否持久化,true表示持久化,false表示非持久化,持久化可以将交换机存盘,在服务器重启的时候不会丢失相关数据。
- autoDelete 是否自动删除,true表示自动删除,false表示不自动删除。自动删除是指和该交换机绑定的队列或其它交换机解除绑定关系,而不是交换机与生产者断开时RabbitMQ将此交换机删除。
- internal 是否将此交换机设置为内置交换机,true是表示为内置交换机,false表示非内置交换机,默认为false,当交换机被设置为内置时,此交换机只能用于RabbitMQ内部使用,生产者无法将消息发送到此交换机,只能通过交换机路由到此交换机。
- arguments 扩展参数,用户扩展AMQP定制化协议,比如:alternate-exchange(备份交换机,表示该交换机为备份交换机,备份交换器是为了实现没有路由到队列的消息,声明交换机的时候添加属性alternate-exchange,声明一个备用交换机,一般声明为fanout类型,这样交换机收到路由不到队列的消息就会发送到备用交换机绑定的队列中。),后面会将参配置的参数列出。
其它方法
/*
* 声明交换机,该方法不会等待RabbitMQ返回声明是否成功的状态,
* 就自认为声明成功了,在声明的过程种可能因为某种原因交换机声明失败,
* 而此方法并不知道,可能导致生产者无法将消息发送到此交换机上。
*
* @param1 exchange 交换机名称
* @param2 type 交换机类型
* @param3 durable 是否持久化
* @param4 autoDelete 是否自动删除
* @param5 internal 当前Exchange是否用于RabbitMQ内部使用,默认false
* @param6 arguments 扩展参数,用户扩展AMQP定制化协议
*
* @return void
*/
channel.exchangeDeclareNoWait("fanout_exchange",
BuiltinExchangeType.FANOUT, false, true, false, null);
/*
* 根据交换机名称插叙该交换机是否存在
* @param1 exchange 交换机名称
* @return AMQP.Exchange.DeclareOk 用来标识一个交换机是否存在。
* 存在返回 exchange.declare-ok,
* 不存在返回 404,同时Channel也会被关闭。
*/
AMQP.Exchange.DeclareOk declareOk1 = channel.exchangeDeclarePassive("fanout_exchange");
/*
* 删除交换机
*
* @param1 exchange 交换机名称
*/
AMQP.Exchange.DeleteOk deleteOk = channel.exchangeDelete("fanout_exchange");
/*
* 删除交换机没有被使用的交换机
*
* @param1 exchange 交换机名称
* @param2 ifUnused 是否删除未被使用的交换机,
* true表示只有在交换机没有被使用的时候才会被删除,
* false表示无论如何都要删掉。
*/
AMQP.Exchange.DeleteOk deleteOk1 = channel.exchangeDelete("fanout_exchange",true);
/*
* 删除交换机没有被使用的交换机,该方法表示不会等RabbitMQ给是否删除成功的消息,
* 就认为是已经删除了,这个方法可能会因为某种原因导致交换机没有被删除,而以为被删除了。
*
* @param1 exchange 交换机名称
* @param2 ifUnused 是否删除未被使用的交换机,
* true表示只有在交换机没有被使用的时候才会被删除,
* false表示无论如何都要删掉。
*/
channel.exchangeDeleteNoWait("fanout_exchange",true);
队列
声明队列时常用的方法。
/*
* 方法默认创建一个由RabbitMQ命名的
* (类似这种amq.gen-LhQzlgv3GhDOv8PIDabOXA 名称,这种队列也称之为匿名队列)、
* 排他的、自动删除的、非持久化的队列
*/
channel.queueDeclare();
/*
* 声明队列,如果队列不存在会创建队列
* 生产者和消费者都能够使用queueDeclare 来声明一个队列,
* 但是如果消费者在同一个信道上订阅了另一个队列,就无法再声明队列了。
* 必须先取消订阅,然后将信道置为"传输"模式,之后才能声明队列。
*
* @param1 queueName 队列名称,队列名称不可重复
* @param2 durable 队列是否持久化,true表示队列为持久化, 持久化的队列会存盘,
* 在服务器重启的时候会保证不丢失相关信息
* @param3 exclusive 设置是否排他,
* true表示队列为排他的, 如果一个队列被设置为排他队列,
* 该队列仅对首次声明它的连接可见, 并在连接断开时自动删除,
* (这里需要注意三点:1.排他队列是基于连接Connection可见的,
* 同一个连接的不同信道Channel是可以同时访问同一连接创建的排他队列;
* "首次"是指如果一个连接己经声明了一个排他队列,其他连接是不允许建立同名的排他队列的,
* 这个与普通队列不同;即使该队列是持久化的,一旦连接关闭或者客户端退出,
* 该排他队列都会被自动删除,这种队列适用于一个客户端同时发送和读取消息的应用场景)
* @param4 autoDelete 设置是否自动删除。为true 则设置队列为自动删除。
* 自动删除的前提是, 至少有一个消费者连接到这个队列,
* 之后所有与这个队列连接的消费者都断开时,才会自动删除。
* 不能把这个参数错误地理解为: "当连接到此队列的所有客户端断开时,这个队列自动删除",
* 因为生产者客户端创建这个队列,或者没有消费者客户端与这个队列连接时,都不会自动删除这个队列
* @param5 arguments 可以设置队列其它参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等
*
* @throws IOException
*
* @return DeclareOk
*/
AMQP.Queue.DeclareOk declareOk = channel.queueDeclare("hello", false, false, true, null);
/*
* 方法的返回值也是void, 表示不需要服务器的任何返回, 同时也需要注意,
* 在调用完queueDeclareNoWait方法之后, 紧接着使用声明的队列时有可能发生异常情况
*
* @params 参数 参数和上面的方法参数一致
* @throws IOException
* @return void
*/
channel.queueDeclareNoWait("hello", false, false, true, null);
/*
*这个方法用来检测相应的队列是否存在,
* 如果存在则正常返回, 如果不存在则抛出异常,
* 404 channel excaption, 同时Channel也会被关闭
*
* @param1 queueName 队列名称
* @throws IOException
*
* @return DeclareOk
*/
AMQP.Queue.DeclareOk declareOk1 = channel.queueDeclarePassive("hello");
/*
* 扇出队列
*
* @param1 queueName 队列名称
* @throws IOException
* @return DeleteOk
*/
AMQP.Queue.DeleteOk deleteOk = channel.queueDelete("hello");
/*
* 扇出队列
*
* @param1 queueName 队列名称
* @param2 ifUnused 是否在交换器没有使用的情况下删除,
* 如果设置true表示只有在此队列没有被交换机使用的情况下才会被删除,
* false表示无论如何这个队列都要被删除
* @param3 ifEmpty true表示在队列为空(队列里面没有任何消息堆积)的情况下才能够删除,false反之
* @throws IOException
* @return DeleteOk
*/
AMQP.Queue.DeleteOk deleteOk1 = channel.queueDelete("hello",false,false);
/*
* 扇出队列,不等待
*
* @param1 queueName 队列名称
* @param2 ifUnused 是否在交换器没有使用的情况下删除,
* 如果设置true表示只有在此队列没有被交换机使用的情况下才会被删除,
* false表示无论如何这个队列都要被删除
* @param3 ifEmpty true表示在队列为空(队列里面没有任何消息堆积)的情况下才能够删除,false反之
* @throws IOException
* @return void
*/
channel.queueDeleteNoWait("hello",false,false);
/*
* 扇出队列内容,区别于queueDelete ,这个方法用来清空队列中的内容,而不删除队列本身
* @param1 queueName 队列名称
* @throws IOException
* @return PurgeOk
*/
AMQP.Queue.PurgeOk purgeOk = channel.queuePurge("hello");
参数解释
- queueName:队列名称,队列名称不可重复
- durable:队列是否持久化,true表示队列为持久化, 持久化的队列会存盘,在服务器重启的时候会保证不丢失相关信息
- exclusive:设置是否排他, true表示队列为排他的, 如果一个队列被设置为排他队列, 该队列仅对首次声明它的连接可见, 并在连接断开时自动删除, (这里需要注意三点:1.排他队列是基于连接Connection可见的, 同一个连接的不同信道Channel是可以同时访问同一连接创建的排他队列;"首次"是指如果一个连接己经声明了一个排他队列,其他连接是不允许建立同名的排他队列的,这个与普通队列不同;即使该队列是持久化的,一旦连接关闭或者客户端退出,该排他队列都会被自动删除,这种队列适用于一个客户端同时发送和读取消息的应用场景)
- autoDelete:设置是否自动删除。为true 则设置队列为自动删除。自动删除的前提是, 至少有一个消费者连接到这个队列,之后所有与这个队列连接的消费者都断开时,才会自动删除。不能把这个参数错误地理解为: "当连接到此队列的所有客户端断开时,这个队列自动删除",因为生产者客户端创建这个队列,或者没有消费者客户端与这个队列连接时,都不会自动删除这个队列。
- arguments:置队列的有效期,消息的最大长度,队列的消息生命周期等等
绑定
交换机与队列的绑定
/*
* 将队列与交换机进行绑定
*
* @param1 queueName 队列名称
* @param2 exchangeName 交换器的名称
* @param3 routingKey 用来绑定队列和交换器的路由键;
* @param4 argument 定义绑定的一些参数
*
* @throws IOException
* @return BindOk
*/
AMQP.Queue.BindOk bindOk = channel.queueBind("queue_name", "exchange_name", "binding_key", null);
/*
* 将队列与交换机进行绑定
*
* @param1 queueName 队列名称
* @param2 exchangeName 交换器的名称
* @param3 routingKey 用来绑定队列和交换器的路由键;
*
* @throws IOException
* @return BindOk
*/
AMQP.Queue.BindOk bindOk1 = channel.queueBind("queue_name", "exchange_name", "binding_key");
/*
* 将队列与交换机进行绑定 不等待返回,该方法使用时可能会出问题,
* 因为你不知道绑定关系是否创建成功。
*
* @param1 queueName 队列名称
* @param2 exchangeName 交换器的名称
* @param3 routingKey 用来绑定队列和交换器的路由键;
* @param4 argument 定义绑定的一些参数
*
* @throws IOException
* @return void
*/
channel.queueBindNoWait("queue_name", "exchange_name", "binding_key", null);
/*
* 解除队列与交换机之间的绑定关系
*
* @param1 queueName 队列名称
* @param2 exchangeName 交换器的名称
* @param3 routingKey 用来绑定队列和交换器的路由键;
* @param4 argument 定义绑定的一些参数
*
* @throws IOException
* @return UnbindOk
*/
AMQP.Queue.UnbindOk unbindOk = channel.queueUnbind("queue_name", "exchange_name", "binding_key", null);
/*
* 解除队列与交换机之间的绑定关系
*
* @param1 queueName 队列名称
* @param2 exchangeName 交换器的名称
* @param3 routingKey 用来绑定队列和交换器的路由键;
*
* @throws IOException
* @return UnbindOk
*/
AMQP.Queue.UnbindOk unbindOk1 = channel.queueUnbind("queue_name", "exchange_name", "binding_key");
交换机与交换机的绑定
生产者发送消息至交换器source 中,交换器source 根据路由键找到与其匹配的另一个交换器destination , 井把消息转发到destination 中, 进而存储在.destination 绑定的队列queue 中。
/*
* 声明目的地交换机
*/
channel.exchangeDeclare("destination_exchange",
BuiltinExchangeType.DIRECT, false, true, false, null);
/*
* 声明源交换机
*/
channel.exchangeDeclare("source_exchange",
BuiltinExchangeType.FANOUT, false, true, false, null);
/*
* 将交换器与交换器绑定
*
* @param1 destination 目标交换机名称
* @param2 source 源头交换机名称
* @param3 routingKey 绑定关系key
* @param4 arguments 其它自定义配置参数
*
* @throws IOException
* @return BindOk
*/
AMQP.Exchange.BindOk bindOk = channel.exchangeBind("destination_exchange",
"source_exchange", "routingKey", null);
/*
* 将交换器与交换器绑定
*
* @param1 destination 目标交换机名称
* @param2 source 源头交换机名称
* @param3 routingKey 绑定关系key
*
* @throws IOException
* @return BindOk
*/
AMQP.Exchange.BindOk bindOk1 = channel.exchangeBind("destination_exchange",
"source_exchange", "routingKey");
/*
* 将交换器与交换器绑定,不等待返回
*
* @param1 destination 目标交换机名称
* @param2 source 源头交换机名称
* @param3 routingKey 绑定关系key
* @param4 arguments 其它自定义配置参数
*
* @throws IOException
* @return void
*/
channel.exchangeBind("destination_exchange",
"source_exchange", "routingKey", null);
发送消息
生产者将消息发送到交换机。
/*
* 声明队列,如果队列不存在会创建队列,如果队列存在会报错,提示队列存在
*
* @param1 队列名称,队列名称不可重复
* @param2 队列是否持久化,是指队列中的消息是否持久化,正常是不需要持久化的。
* @param3 是否排他,也就是是否私有,只能被一个消费者进行消费,true是排他性,
* 会对当前队列加锁,其他的通道不能访问,false 则是共享
* @param4 是否自动删除,这里是指该队列是否会被自动删除,
* 当最后一个消费者断开连接之后是否删除该队列。true是会自动删除
* @param5 可以设置队列其它参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等
*
* @return DeclareOk
*
* @throws IOException
*
*/
AMQP.Queue.DeclareOk declareOk = channel.queueDeclare("queue_name", true, false, true, null);
接收消息
消费者接收消息。
/*
* 消费者订阅队列,在某个队列上注册消费者,在这个队列中有消息时,
* 就会把消息转发给此Channel来处理,如果这个队列有多个消费者,
* RabbitMQ则会采用轮转的方式将消息分发给各个消费者。
*
* @param1 队列名称 将自己注册到那个队列中,以便消费那个队列的消息。
* @param2 消息成功接收后是否要自动应答,当设置为true时,代表自动应答,false时代表手动应答。
* @param3 当队列中有消息是,rabbitmq调用的回调接口,用于将消息传递过来。
* @param4 rabbitmq取消该消费者对信道中队列的订阅时,调用的回调接口,
* 如被订阅的队列被删除时,rabbitmq就会通过该接口通知消费者,
* 以便消费者做相应处理。消费者可以根据consumerTag标识,
* 主动调用channel.basicCancel(consumerTag)方法进行对RabbitMQ队列的注册关系进行解除。
* @return 该方法的返回值是该消费者注册到RabbitMQ之后,RabbitMQ给生成的一个该消费者的唯一标识。
*/
String consumerTag = channel.basicConsume("hello", autoAck, deliverCallback, cancelCallback);