详解RabbitMq之交换机

rabbitMq有四种类型的交换机fanoutdirecttopicheaders

一、 不用交换机的队列

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);  
        }   

猜你喜欢

转载自blog.csdn.net/yejunjian007/article/details/80259931