RabbitMQ的使用(三)消息队列的订阅模式

其实如果直接将消息发送到对列中不仅开销较大,而且耦合度也很大,通常我们都是将生产者将消息发送到Exchange(交换器,下图中的X),再通过Binding将Exchange与Queue关联起来。

RabbitMQ的使用(三)消息队列的订阅模式_第1张图片

     在绑定(Binding)Exchange与Queue的同时,一般会指定一个binding key。在绑定多个Queue到同一个Exchange的时候,这些Binding允许使用相同的binding key。
    生产者在将消息发送给Exchange的时候,一般会指定一个routing key,来指定这个消息的路由规则,生产者就可以在发送消息给Exchange时,通过指定routing key来决定消息流向哪里。
    RabbitMQ常用的Exchange Type有三种:fanout、direct、topic。
    fanout:把所有发送到该Exchange的消息投递到所有与它绑定的队列中。
    direct:把消息投递到那些binding key与routing key完全匹配的队列中。

    topic:将消息路由到binding key与routing key模式匹配的队列中

我们先实现最基础的fanout模式的一个普通交换机队列 

生产者:

package com.hc.exchange;

import com.hc.mqutil.MqUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Product {
     private final static String EXCHANGE_NAME="exchange_fanout";
     public static void main(String[] args) throws Exception {
    	 Connection connection=MqUtil.getConnection();
    	 Channel channel=connection.createChannel();
    	 //声明交换机
    	 channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
    	 for(int i=0;i<50;i++){
 			String message="我是第"+i+"条消息";
 			 channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes()); 
 			 System.out.println(message);
 		    Thread.sleep(i*10);
 		}
    	 channel.close();
    	 connection.close();
    	
    	 
	}
	
}

消费者1

package com.hc.exchange;

import com.hc.mqutil.MqUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

public class Consumer1 {
    private final static String QUEUE_NAME="queuetest";
    private final static String EXCHANGE_NAME="exchange_fanout";
    public static void main(String[] args) throws Exception {
    	 Connection connection=MqUtil.getConnection();
    	 Channel channel=connection.createChannel();
    	 //声明队列
    	 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
    	 //绑定到交换机
    	 channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
    	 channel.basicQos(1);
    	 //声明消费者
    	 QueueingConsumer consumer=new QueueingConsumer(channel);
    	 //监听队列,手动返回
    	 channel.basicConsume(QUEUE_NAME, false, consumer);
    	 
    	 while(true){
        	 QueueingConsumer.Delivery delivery=consumer.nextDelivery();
             String message=new  String(delivery.getBody());
             System.out.println(message);
             Thread.sleep(10);

             channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
    	 }
    	
	}
    
}

消费者2

package com.hc.exchange;

import java.io.IOException;

import cn.itcast.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

public class Consumer2 {
	   private final static String QUEUE_NAME="queuetest";
	    private final static String EXCHANGE_NAME="exchange_fanout";
	public static void main(String[] args) throws Exception {
		 // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();

        // 声明队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 绑定队列到交换机
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");

        // 同一时刻服务器只会发一条消息给消费者
        channel.basicQos(1);

        // 定义队列的消费者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        // 监听队列,手动返回完成
        channel.basicConsume(QUEUE_NAME, false, consumer);

        // 获取消息
        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" 搜索系统: '" + message + "'");
            Thread.sleep(10);

            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
	}
}


你可能感兴趣的:(RabbitMQ的使用(三)消息队列的订阅模式)