1.fanout 发布/订阅
在上一篇中队列都指定了名称,现在我们需要所有的日志信息,而不只是其中的一个。如果要做这样的队列,我们需要2件事,一个就是获取一个新的空的队列,这样我就需要创建一个随机名称的队列,最好让服务器帮我们做出选择,第一个就是我们断开用户的队列,应该自动进行删除。
生产者:
/**
* 发布/订阅 生产者
*/
public class EmitLog {
public static final String EXCHANGE_NAME = "logs";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME,"fanout");//fanout表示分发,所有的消费者得到同样的队列信息
for (int i = 0 ; i<10;i++){
String message = "hello fanout "+i;
channel.basicPublish(EXCHANGE_NAME,"",null,message.getBytes("utf-8"));
System.out.println("emitLog send '"+message+"'");
}
channel.close();
connection.close();
}
}
消费者(两个消费者代码一样):
/**
* 消费者
*/
public class ReceiveLogs1 {
public static final String EXCHANGE_NAME = "logs";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME,"fanout");
//产生一个随机的队列名称
String queue = channel.queueDeclare().getQueue();
//对队列进行绑定
channel.queueBind(queue,EXCHANGE_NAME,"");
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("ReceiveLogs1 Received '" + message + "'");
}
};
channel.basicConsume(queue,true,consumer); //从队列中删除
}
}
查看结果:
生产者:
消费者1:
消费者2:
2.Routing 按路线发布接收
生产者:
/**
* routing key 匹配,Message就会被传递到相应的queue中
*/
public class RoutingSendDirect {
private static final String EXCHANGE_NAME = "direct_logs";
// 路由关键字
private static final String[] routingKeys = new String[]{"info" ,"warning", "error"};
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明交换机,注意是direct
channel.exchangeDeclare(EXCHANGE_NAME,"direct");
//发送信息
for (String key : routingKeys){
String message = "RoutingSendDirect Send the message level:" + key;
channel.basicPublish(EXCHANGE_NAME,key,null,message.getBytes("utf-8"));
System.out.println("RoutingSendDirect Send"+key +"':'" + message);
}
channel.close();
connection.close();
}
}
消费者1:
/**
* 消费者1
*/
public class ReceiveLogsDirect1 {
// 交换器名称
private static final String EXCHANGE_NAME = "direct_logs";
// 路由关键字
private static final String[] routingKeys = new String[]{"error"};
public static void main(String[] args)throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明交换器
channel.exchangeDeclare(EXCHANGE_NAME,"direct");
//获取匿名队列名称
String queue = channel.queueDeclare().getQueue();
//根据路由关键字进行绑定
for (String key : routingKeys) {
channel.queueBind(queue,EXCHANGE_NAME,key);
System.out.println("ReceiveLogsDirect1 exchange:"+EXCHANGE_NAME+"," +
" queue:"+channel+", BindRoutingKey:" + key);
}
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("ReceiveLogsDirect1 Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queue,true,consumer);
}
}
消费者2:
/**
* 消费者2
*/
public class ReceiveLogsDirect2 {
// 交换器名称
private static final String EXCHANGE_NAME = "direct_logs";
// 路由关键字
private static final String[] routingKeys = new String[]{"info" ,"warning","error"};
public static void main(String[] args)throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明交换器
channel.exchangeDeclare(EXCHANGE_NAME,"direct");
//获取匿名队列名称
String queue = channel.queueDeclare().getQueue();
//根据路由关键字进行绑定
for (String key : routingKeys) {
channel.queueBind(queue,EXCHANGE_NAME,key);
System.out.println("ReceiveLogsDirect2 exchange:"+EXCHANGE_NAME+"," +
" queue:"+channel+", BindRoutingKey:" + key);
}
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("ReceiveLogsDirect2 Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queue,true,consumer);
}
}
查看结果:
生产者:
消费者1:
消费者2:
3.Topics 模糊匹配
* : 可以替代一个词
# :可以替代0个或更多词
生产者:
/**
* 模糊匹配队列
* 生产者
*/
public class TopicSend {
public static final String EXCHANGE_NAME = "topic_logs";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明一个匹配模式的交换机
channel.exchangeDeclare(EXCHANGE_NAME,"topic");
//待发送的消息
String[] routingKeys=new String[]{
"quick.orange.rabbit",
"lazy.orange.elephant",
"quick.orange.fox",
"lazy.brown.fox",
"quick.brown.fox",
"quick.orange.male.rabbit",
"lazy.orange.male.rabbit"
};
//发送消息
for (String key:routingKeys ) {
String message = "From "+key+" routingKey' s message!";
channel.basicPublish(EXCHANGE_NAME,key,null,message.getBytes("utf-8"));
System.out.println("TopicSend Sent '" + key + "':'" + message + "'");
}
channel.close();
connection.close();
}
}
消费者1:
/**
* 消费者1
*/
public class ReceiveLogsTopic1 {
private static final String EXCHANGE_NAME = "topic_logs";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明一个匹配模式的交换机
channel.exchangeDeclare(EXCHANGE_NAME,"topic");
String queue = channel.queueDeclare().getQueue();
//路由关键字
String[] routingKeys = new String[]{"*.orange.*"};
//绑定路由
for (String key : routingKeys){
channel.queueBind(queue,EXCHANGE_NAME,key);
System.out.println("ReceiveLogsTopic1 exchange:" + EXCHANGE_NAME + ", queue:" + queue + ", BindRoutingKey:" + key);
}
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("ReceiveLogsTopic1 Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queue,true,consumer);
}
}
消费者2:
/**
* 消费者2
*/
public class ReceiveLogsTopic2 {
private static final String EXCHANGE_NAME = "topic_logs";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明一个匹配模式的交换机
channel.exchangeDeclare(EXCHANGE_NAME,"topic");
String queue = channel.queueDeclare().getQueue();
//路由关键字
String[] routingKeys = new String[]{"*.*.rabbit", "lazy.#"};
//绑定路由
for (String key : routingKeys){
channel.queueBind(queue,EXCHANGE_NAME,key);
System.out.println("ReceiveLogsTopic2 exchange:" + EXCHANGE_NAME + ", queue:" + queue + ", BindRoutingKey:" + key);
}
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("ReceiveLogsTopic2 Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queue,true,consumer);
}
}
查看结果:
生产者:
消费者1:
消费者2: