生产者:
package mq.fanout;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeoutException;
/**
* @description 通过自定义转发器给每个队列发送日志
* @author: gaobh
* @date: 2018/4/25 14:35
* @version: v1.0
*/
public class MqLogProviderDemo {
private final static String EXCHANGE_NAME = "ex_log";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
//fanout类型转发器把所有它接收到的消息广播到所有他所知道的队列
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String message = new Date().toLocaleString() + " : fanout something";
//往转发器上发送消息
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
System.out.println("[x] Sent '" + message + "'");
channel.close();
connection.close();
}
}
消费者1:
package mq.fanout;
import com.rabbitmq.client.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeoutException;
/**
* @description 日志消费者 打印到日志文件
* @author: gaobh
* @date: 2018/4/25 14:42
* @version: v1.0
*/
public class MqLogConsumer1Demo {
private final static String EXCHANGE_NAME = "ex_log";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
//创建一个非持久的、唯一的且自动删除的队列
String queueName = channel.queueDeclare().getQueue();
//为转发器指定一个队列,设置binding
channel.queueBind(queueName, EXCHANGE_NAME, "");
System.out.println(" [*] Waiting for message.To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
String dir = "e://logs";
String logFileName = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
File file = new File(dir, logFileName + ".txt");
FileOutputStream fos = new FileOutputStream(file, true);
fos.write((message + "\r\n").getBytes());
fos.flush();
fos.close();
}
};
channel.basicConsume(queueName,true,consumer);
}
}
这个消费者意图是将收到的生产者发布的消息打印在后台日志文件里面,其实这个不是demo的关键之处,关键之处在于体会如何应用fanout类型的交换器实现消息的生产消费。demo里面创建的是临时队列,并没有指定特定的队列名称也没有持久化。
消费者2:
package mq.fanout;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @description 日志消费者 打印到控制台
* @author: gaobh
* @date: 2018/4/25 14:42
* @version: v1.0
*/
public class MqLogConsumer2Demo {
private final static String EXCHANGE_NAME = "ex_log";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
//创建一个非持久的、唯一的且自动删除的队列
String queueName = channel.queueDeclare().getQueue();
//为转发器指定一个队列,设置binding
channel.queueBind(queueName, EXCHANGE_NAME, "");
System.out.println(" [*] Waiting for message.To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(queueName,true,consumer);
}
}
这个消费者等同与消费者1,只是将收到的消息打印在了控制台。
注:测试程序的时候,要先启动两个消费者,再启动生产者,这样可以很明显的观察出变化以及打印结果。
同时可以观察一下,RabbitMQ的后台管理界面的变化:
这两个就是刚刚临时创建的两个队列。点进去可以看到队列的生成消费以及配置情况。
主要看这个binding,名为ex_log(我们代码里声明的转换器名称)与该队列进行了绑定。
channel.queueBind(queueName, EXCHANGE_NAME, "");
通过这句代码实现的绑定。消费者2的情况类似。