rabbitmq学习(三):rabbitmq之扇形交换机、主题交换机
前言
上篇我们学习了rabbitmq的作用以及直连交换机的代码实现,这篇我们继续看如何用代码实现扇形交换机和主题交换机
一、扇形交换机
1.生产者
/**
* 生产者
*/
public class LogProducer {
//交换机名称
public final static String EXCHANGE_NAME = "logs"; public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = null;
Channel channel = null;
try {
connection = connectionFactory.newConnection();
channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME,"fanout"); for (int i = 0; i < 5;i++){
String message = "Hello Rabbit " + i;
channel.basicPublish(EXCHANGE_NAME,"",null,message.getBytes());
System.out.println("EmitLog send message " + message);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
channel.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
} }
}
}
2.消费者
Consumer1
/**
* 消费者
*/
public class Consumer1 {
public final static String EXCHANGE_NAME = "logs"; public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = null;
Channel channel = null;
try {
connection = connectionFactory.newConnection();
channel = connection.createChannel();
String queueName = channel.queueDeclare().getQueue();
//声明一个交换机,发布模式为fanout-扇形
channel.exchangeDeclare(EXCHANGE_NAME,"fanout");
//将队列和交换机绑定起来,因为扇形交换机和路由键无关,所以这里路由键设为空字符串即可
channel.queueBind(queueName,EXCHANGE_NAME,""); QueueingConsumer consumer = new QueueingConsumer(channel);
//当连接断开时,队列会自动被删除
channel.basicConsume(queueName,true,consumer);
System.out.println("ReceiveLogTopic1 Waitting for message");
while (true){
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("ReceiveLogTopic1 receives message " + message);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Cosumer2
/**
* 消费者2
*/
public class Consumer2 {
public final static String EXCHANGE_NAME = "logs"; public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = null;
Channel channel = null;
try {
connection = connectionFactory.newConnection();
channel = connection.createChannel();
String queueName = channel.queueDeclare().getQueue();
//声明一个交换机,发布模式为fanout-扇形
channel.exchangeDeclare(EXCHANGE_NAME,"fanout");
//将队列和交换机绑定起来,因为扇形交换机和路由键无关,所以这里路由键设为空字符串即可
channel.queueBind(queueName,EXCHANGE_NAME,""); QueueingConsumer consumer = new QueueingConsumer(channel);
//当连接断开时,队列会自动被删除
channel.basicConsume(queueName,true,consumer);
System.out.println("ReceiveLog2 Waitting for message");
while (true){
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("ReceiveLog2 receives message " + message);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
先启动Consumer1,Consumer2,再启动LogProducer。结果如下:
LogProducer:

Consumer1:

Consumer2:

从输出结果中我们可以看出,扇形交换机所接受到的消息会被分发到所有绑定到该交换机上的队列中,和路由键无关。
二、主题交换机
1.生产者
/**
* 生产者
*/
public class Producer {
private static final String EXCHANGE_NAME = "topic_logs";
// 路由关键字
private static final 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"}; public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = null;
Channel channel = null;
try {
connection = connectionFactory.newConnection();
channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, "topic"); //循环发送具有不同routing key的message
for (String routingKey : routingKeys) {
String message = routingKey + "--->biu~";
channel.basicPublish(EXCHANGE_NAME, routingKey, null, message.getBytes());
System.out.println("Producer -> routingkey: " + routingKey + ", send message " + message);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
channel.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
} }
}
}
2.消费者
Consumer1
/**
* 消费者1
*/
public class Consumer1 {
private static final String EXCHANGE_NAME = "topic_logs";
// 路由关键字
private static final String[] routingKeys = new String[]{"*.orange.*"}; public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = null;
Channel channel = null;
try {
connection = connectionFactory.newConnection();
channel = connection.createChannel();
//声明队列
String queueName = channel.queueDeclare().getQueue();
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, "topic"); //将队列与交换器用routingkey绑定起来
for (String routingKey : routingKeys) {
channel.queueBind(queueName, EXCHANGE_NAME, routingKey);
System.out.println("Consumer1 -> queue: " + queueName + ", exchange_name: " + EXCHANGE_NAME + ", routingKey: " + routingKey);
} //接收消息
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, consumer);
System.out.println("Consumer1 waitting for message"); while (true){
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody(), "UTF-8");
Envelope envelope = delivery.getEnvelope();
String routingKey = envelope.getRoutingKey();
System.out.println("Consumer1 receive message " + message + ", routingKey: " + routingKey);
} } catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Consumer2
/**
* 消费者2
*/
public class Consumer2 {
private static final String EXCHANGE_NAME = "topic_logs";
// 路由关键字
private static final String[] routingKeys = new String[]{"*.*.rabbit", "lazy.#"}; public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = null;
Channel channel = null;
try {
connection = connectionFactory.newConnection();
channel = connection.createChannel();
//声明队列
String queueName = channel.queueDeclare().getQueue();
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, "topic"); //将队列与交换器用routingkey绑定起来
for (String routingKey : routingKeys) {
channel.queueBind(queueName, EXCHANGE_NAME, routingKey);
System.out.println("Consumer2 -> queue: " + queueName + ", exchange_name: " + EXCHANGE_NAME + ", routingKey: " + routingKey);
} //接收消息
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, consumer);
System.out.println("Consumer2 waitting for message"); while (true){
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody(), "UTF-8");
Envelope envelope = delivery.getEnvelope();
String routingKey = envelope.getRoutingKey();
System.out.println("Consumer2 receive message " + message + ", routingKey: " + routingKey);
} } catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
同样先运行消费者,再运行生产者,结果如下:
Producer:

Consumer1:

Consumer2:

由运行结果我们可以看到:消息被交换机按照模式路由键的规则路由到相应的队列中。
代码gitbu地址:https://github.com/wutianqi/rabbitmq-learn.git
参考资料:https://www.cnblogs.com/LipeiNet/p/5978276.html
rabbitmq学习(三):rabbitmq之扇形交换机、主题交换机的更多相关文章
- rabbitMQ第三篇:采用不同的交换机规则
在上一篇我们都是采用发送信息到队列然后队列把信息在发送到消费者,其实实际情况并非如此,rabbitMQ其实真正的思想是生产者不发送任何信息到队列,甚至不知道信息将发送到哪个队列.相反生产者只能发送信息 ...
- RabbitMq学习笔记——RabbitMQ C的使用
1.需要用到的参数: 主机名:hostname.端口号:port.交换器:exchange.路由key:routingkey .绑定路由:bindingkey.用户名:user.密码:psw,默认用户 ...
- rabbitmq系列五 之主题交换机
1.主题 在前面的例子中,我们对日志系统进行了改进.使用了direct交换机代替了fanout交换机,从只能盲目的广播消息改进为有可能选择性的接收日志. 尽管直接交换机能够改善我们的日志系统,但是它也 ...
- Rabbitmq消息队列(六) 主题交换机
1.简介 前面学习了有选择性的接收消息,但是却没有办法基于多个标准来接收消息.为了实现这个目的,接下来我们学习如何使用另一种更复杂的交换机 —— 主题交换机. 2.主题交换机 发送到主题交换机(top ...
- 【c#】RabbitMQ学习文档(三)Publish/Subscribe(发布/订阅)
(本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个任务会被交付给一个[工人].在这一部分我们将做一些完全不同的事情--我们将向多个 ...
- rabbitmq学习(二):rabbitmq(消息队列)的作用以及rabbitmq之直连交换机
前言 上篇介绍了AMQP的基本概念,组成及其与rabbitmq的关系.了解了这些东西后,下面我们开始学习rabbitmq(消息队列)的作用以及用java代码和rabbitmq通讯进行消息发布和接收.因 ...
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- 学习RabbitMQ(三)
1 用户注册后(会立即提示注册成功),过一会发送短信和邮件通知 发布/订阅模型 以上模式一般是用户注册成功后,写入一条数据到mysql,在发送一条消息到MQ! 如果不用消息中间件(或者简单的做成异步发 ...
- RabbitMQ学习系列(三): C# 如何使用 RabbitMQ
上一篇已经讲了Rabbitmq如何在Windows平台安装,还不了解如何安装的朋友,请看我前面几篇文章:RabbitMQ学习系列一:windows下安装RabbitMQ服务 , 今天就来聊聊 C# 实 ...
随机推荐
- 2.4 The Object Model -- Computed Properties and Aggregate Data with @each(计算的属性和使用@each聚合数据)
1. 通常,你可能有一个计算的属性依赖于数组中的所有元素来确定它的值.例如,你可能想要计算controller中所有todo items的数量,以此来确定完成了多少任务. export default ...
- PHP curl模拟浏览器采集阿里巴巴的实现代码
<?php set_time_limit(0); function _rand() { $length=26; $chars = "0123456789abcdefghijklmnop ...
- PHP搞笑注释代码-佛祖配美女
//////////////////////////////////////////////////////////////////// // _ooOoo_ // // o8888888o // / ...
- Python3.x:定时任务实现方式
Python3.x:定时任务实现方式 Python3.x下实现定时任务的方式有很多种方式. 一.循环sleep: 最简单的方式,在循环里放入要执行的任务,然后sleep一段时间再执行.缺点是,不容易控 ...
- 20145204 《Java程序设计》第1周学习总结
20145204 <Java程序设计>第1周学习总结 教材学习内容总结 本周经过不断的钻研课本,及看一些老师的视频,我对Java有了一个全新的认知.是的,Java和C都是一种语言,但是Ja ...
- 第7章 调试和错误处理 7.1.1 VS中的调试
VS有一个输出窗口,调用方法是 需要注意的是,这个窗口有两个模式,使用其中的下拉列表就可以选择这些模式.可以在Build和Debug模式之间切换.Build和Debug模式分别显示编译和运行期间的信息 ...
- Ubuntu 安装Docker
参考:官网 安装依赖包: $ sudo apt-get update $ sudo apt-get install -y --no-install-recommends \ linux-image-e ...
- python第三方库PIL安装的各种坑
PIL python的图像处理库,pycharm安装屡次失败,始终报错 果断换依旧报错,查遍所有博客, 有给pip加参数的,pip install PIL --allow-external PIL - ...
- MySQL 5.7.17 Windows安装和启动
1.在官网http://dev.mysql.com/downloads/下载 MySQL Community Server 2.解压后是这个样子(5.7.18解压后没有my-default.ini文件 ...
- shell 判断字符串长度是否为0
test.sh #!/bin/bash echo "enter the string:" read filename if test -z $filename ; then ech ...