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# 实 ...
随机推荐
- Python实现支付宝在线支付
windows系统安装Python虚拟环境 首先保证你的系统已经安装好了Python 安装virtualenv C:\WINDOWS\system32>pip3 install virtuale ...
- Python 自带IDLE 如何打开
- 【运维技术】shell脚本实现线程挂掉,自动重启功能
由于分布式系统的流行,服务器上面部署的项目都是多实例的.而我又希望有一个功能,当服务器出现异常情况能够自动重启实例. 所以我想到了使用shell脚本监控实例进程id,如果不存在的话,就重启对应的实例. ...
- IP地址与MAC地址
作者:知乎用户链接:https://www.zhihu.com/question/21546408/answer/28155896来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- Redis学习笔记之Linux下Redis的安装和部署
0x00 Redis介绍 Redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相 ...
- Vue学习笔记之Vue学习前的准备工作
0x00 起步 1.扎实的HTML/CSS/Javascript基本功,这是前置条件. 2.不要用任何的构建项目工具,只用最简单的<script>,把教程里的例子模仿一遍,理解用法.不推荐 ...
- 2017-2018-1 JaWorld 团队作业--冲刺4
2017-2018-1 JaWorld 团队作业--冲刺4 (20162305) 总体架构 我们本次团队项目设定为基于Android系统Java架构下的打飞机小游戏 游戏中所有模型的原型设定是精灵,因 ...
- Makefile解析(最简单的LED)
①led_sp.bin: start.o led.o #led_sp.bin是由 start.o 和 led.o 生成 ②arm-linux-ld -Ttext 0x0 -o led_sp.elf $ ...
- 微信小程序路过——新手不要错过哦!
应该算是入门篇, 从我怎么0基础然后沿着什么方向走,遇到的什么坑,如何方向解决,不过本人接触不是很多,所以也就了解有限. 小程序的前提: 1.小程序大小不允许超过2M.(也就是本地图片,大图精图不要在 ...
- springboot2 统一异常处理
统一异常处理,不需要在每一层上单独捕获异常,只需要关注业务的开发: 代码如下: @RestControllerAdvice @Slf4j public class GlobalExceptionHan ...