rabbitMq有四种类型的交换机fanout、direct、topic、headers
一、 不用交换机的队列
API介绍
/*
* 创建队列
* queue:队列名称
* durable:队列持久化标志,ture为持久化
* exclusive:排他队列
* autoDelete:自动删除
* arguments:Map类型,关于队列及队列中消息的详细设置
*/
channel.queueDeclare(queue, durable, exclusive, autoDelete, arguments)
arguments参数 请参考
生产者示例:
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//发送10条消息,依次在消息后面附加1-10个点
for (int i = 6; i > 0; i--)
{
String message = "helloworld"+i;
channel.basicPublish("", QUEUE_NAME,null, message.getBytes());
}
消费者示例:
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
QueueingConsumer consumer = new QueueingConsumer(channel);
// 指定消费队列
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
doWork(message);
}
二 、fanout类型的交换机
1、消息与队列匹配规则:fanout类型交换机会将接收到的消息广播给所有与之绑定的队列。
如图所示:这种广播机制,生产者P只关心发给哪个交换机X
消费者C只关心订阅了哪个队列
生产者示例:
// 声明转发器和类型
channel.exchangeDeclare(EXCHANGE_NAME, "fanout" );
String message = "消息1";
// 往转发器上发送消息
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
消费者示例:
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
// 创建一个非持久的、唯一的且自动删除的队列
String queueName = channel.queueDeclare().getQueue();
// 为转发器指定队列,设置binding
channel.queueBind(queueName, EXCHANGE_NAME, "");
QueueingConsumer consumer = new QueueingConsumer(channel);
// 指定接收者,第二个参数为自动应答,无需手动应答
channel.basicConsume(queueName, true, consumer);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
doSomething(message);
}
三 、direct类型的交换机
1、消息分发规则:消息会被推送至绑定键(binding key)和消息发布附带的选择键(routing key)完全匹配的队列。
生产者示例:
chanel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 发布消息至转发器,指定routingkey
chanel.basicPublish(EXCHANGE_NAME, "error", null, message1.getBytes());
chanel.basicPublish(EXCHANGE_NAME, "info", null, message2.getBytes());
消费者示例:
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String queueName = channel.queueDeclare().getQueue();
// 指定binding_key
channel.queueBind(queueName, EXCHANGE_NAME, "error");
channel.queueBind(queueName, EXCHANGE_NAME, "warning");
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, consumer);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
doSomething(message);
}
四 、topic类型的交换机
1、消息分发规则:一个附带特殊的选择键将会被转发到绑定键与之匹配的队列中。可以简单理解为模糊匹配
四 、headers类型的交换机
1、消息分发规则:headers类型的交换机分发消息不依赖routingKey,是使用发送消息时basicProperties对象中的headers来匹配的。headers是一个键值对类型,发送者发送消息时将这些键值对放到basicProperties对象中的headers字段中,队列绑定交换机时绑定一些键值对,当两者匹配时,队列就可以收到消息。匹配模式有两种,在队列绑定到交换机时用x-match来指定,all代表定义的多个键值对都要满足,而any则代码只要满足一个就可以了。fanout,direct,topic exchange的routingKey都需要要字符串形式的,而headers exchange则没有这个要求,因为键值对的值可以是任何类型。
生产者示例:
//声明转发器和类型headers
channel.exchangeDeclare(EXCHANGE_NAME, ExchangeTypes.HEADERS,false,true,null);
String message = "消息1";
Map<String,Object> headers = new Hashtable<String, Object>();
headers.put("aaa", "01234");
Builder properties = new BasicProperties.Builder();
properties.headers(headers);
// 指定消息发送到的转发器,绑定键值对headers键值对
channel.basicPublish(EXCHANGE_NAME, "",properties.build(),message.getBytes());
消费者示例:
//声明转发器和类型headers
channel.exchangeDeclare(EXCHANGE_NAME, ExchangeTypes.HEADERS,false,true,null);
channel.queueDeclare(QUEUE_NAME,false, false, true,null);
Map<String, Object> headers = new Hashtable<String, Object>();
headers.put("x-match", "any");//all any
headers.put("aaa", "01234");
headers.put("bbb", "56789");
// 为转发器指定队列,设置binding 绑定header键值对
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME,"", headers);
QueueingConsumer consumer = new QueueingConsumer(channel);
// 指定接收者,第二个参数为自动应答,无需手动应答
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(message);
}