Exchange类型之 fanout:
基本概念:它会把所有发送到该Exchange中的消息,发送到所有与它绑定的Queue中(信息是完整的)。
这是最简单的Exchange类型,没有任何约束。
这里重点是Exchange和Queue的绑定
第三个参数为routingKey,fanout类型并不需要,可以为“”,但不能为null,否则会抛处错误。
channel.queueBind(queueName, exchangeName, "");
发送端:
package sunf.rabbitMQTest;
import java.io.IOException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
/**
* MQ消息发送者测试2(信息多队列整体推送测试)
*
* 这个例子将消息发送到Exchange, 该Exchange为【fanout】类型,消息体不会被分散,而是整体路由到所有与它绑定的queue中。
* 我们在发送端仅仅把消息一次publish进这个Exchange中。
*
* 接收端 ConsumerTest2.java
* 声明queue并与Exchange绑定
* channel.queueDeclare(queueName, false, false, false, null);
* channel.queueBind(queueName, exchangeName, "");
* 每个queueName代表一个不同的queue,每个与Echange绑定的queue都会获得完整的数据
*
* ps:如果同一个queue中的内容被多个consumer接收,信息仍然会被所有消费者均分。
*
* @author SUNF
*
*/
public class Send2 {
final static String exchangeName = "zg2";
public static void main(String[] args) throws IOException, Exception {
ConnectionFactory cf = new ConnectionFactory();
cf.setHost(RabbitMQConstants.VHOST_IP);
Connection conn = cf.newConnection(); //新连接
Channel channel = conn.createChannel();
//声明一个exchange和其类型
channel.exchangeDeclare(exchangeName, "fanout");
for(int i=0;i<5;i++){
String message = "能量+" + i;
//持久化消息
channel.basicPublish(exchangeName, "", null, message.getBytes());
System.out.println("[消息已发送--------------->>" + message);
}
channel.close();
conn.close();
}
}
[消息已发送--------------->>能量+0
[消息已发送--------------->>能量+1
[消息已发送--------------->>能量+2
[消息已发送--------------->>能量+3
[消息已发送--------------->>能量+4
接收端:
接收端用两个线程模拟两个用户,开启两个Queue的情况,由于服务端设置Exchange为fanout,消息完整的推送到所有与该Exchange绑定的Queue中。
package sunf.rabbitMQTest;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
/**
* MQ消息发送者测试2 对应的消费者
* @author SUNF
*
*/
public class ConsumerTest2 {
final static String exchangeName = Send2.exchangeName;
public static void main(String[] args) throws Exception{
//1
new Thread(){
public void run(){
try {
ConsumerTest2.recver("葫芦山","葫芦娃");
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
//2
new Thread(){
public void run(){
try {
ConsumerTest2.recver("阿里巴巴","马云");
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 信息接收方法
* @param queueName
* @param consumerName
* @throws Exception
*/
private static void recver(String queueName, String consumerName) throws Exception {
ConnectionFactory cf = new ConnectionFactory();
cf.setHost(RabbitMQConstants.VHOST_IP);
Connection conn = cf.newConnection();
Channel channel = conn.createChannel();
/*****从此处开始看***/
//声明exchange
channel.exchangeDeclare(exchangeName, "fanout");
//声明queue
channel.queueDeclare(queueName, false, false, false, null);
//绑定Queue与Exchange
channel.queueBind(queueName, exchangeName, "");
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(consumerName+"从【"+queueName+"】接收到消息---->> " + message + "'");
}
}
}
运行结果:
葫芦娃从【葫芦山】接收到消息---->> 能量+0'
葫芦娃从【葫芦山】接收到消息---->> 能量+1'
马云从【阿里巴巴】接收到消息---->> 能量+0'
马云从【阿里巴巴】接收到消息---->> 能量+1'
马云从【阿里巴巴】接收到消息---->> 能量+2'
马云从【阿里巴巴】接收到消息---->> 能量+3'
马云从【阿里巴巴】接收到消息---->> 能量+4'
葫芦娃从【葫芦山】接收到消息---->> 能量+2'
葫芦娃从【葫芦山】接收到消息---->> 能量+3'
葫芦娃从【葫芦山】接收到消息---->> 能量+4'
注意:上面代码中偷懒创建了多个Connection,这是宝贵的资源并不提倡多建。在一个Connection中可以创建多个Channel来传输。