RabbitMQ之交换机
1. 交换机类型
rabbitmq常见有四种交换机类型: direct, topic, fanout, headers.
一般headers都不用,工作中用得较多的是fanout,它会将消息推送到所有绑定在此交换机上的队列中,效率也是这几种交换机中最高的。
交换机是啥? 感觉跟网关差不多,就是路由、转发消息.
下面具体说说几种交换机的使用
2. 交换机的使用
2.1 direct 交换机
direct: 直连 相当于 1 对 1.
生产者----> direct exchange ---> queue ----> 消费者
- // 生产端代码
- public static void main(String[] args) throws Exception {
- //1 创建ConnectionFactory
- ConnectionFactory connectionFactory = new ConnectionFactory();
- connectionFactory.setHost("127.0.0.1");
- connectionFactory.setPort(5672);
- connectionFactory.setVirtualHost("/");
- //2 创建Connection
- Connection connection = connectionFactory.newConnection();
- //3 创建Channel
- Channel channel = connection.createChannel();
- //4 声明
- String exchangeName = "direct_exchange";
- // 5. 路由key, 消费端必须与其一致
- String routingKey = "direct.routingKey";
- //5 发送
- String msg = "this is direct exchange test... ";
- channel.basicPublish(exchangeName, routingKey , null , msg.getBytes());
- }
- // 消费端代码
- public static void main(String[] args) throws Exception {
- ConnectionFactory connectionFactory = new ConnectionFactory() ;
- connectionFactory.setHost("127.0.0.1");
- connectionFactory.setPort(5672);
- connectionFactory.setVirtualHost("/");
- connectionFactory.setAutomaticRecoveryEnabled(true);
- connectionFactory.setNetworkRecoveryInterval(3000);
- Connection connection = connectionFactory.newConnection();
- Channel channel = connection.createChannel();
- //4 声明交换机名称 ,注意它必须与生产端一致
- String exchangeName = "direct_exchange";
- String exchangeType = "direct";
- // 队列名称随便取,意思意思 ,绑定就行
- String queueName = "direct_queue";
- // 必须与生产端一致
- String routingKey = "direct.routingKey";
- //表示声明了一个交换机
- channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
- //表示声明了一个队列
- channel.queueDeclare(queueName, false, false, false, null);
- //建立一个绑定关系:
- channel.queueBind(queueName, exchangeName, routingKey);
- //durable 是否持久化消息
- QueueingConsumer consumer = new QueueingConsumer(channel);
- //参数:队列名称、是否自动ACK、Consumer
- channel.basicConsume(queueName, true, consumer);
- //循环获取消息
- while(true){
- //获取消息,如果没有消息,这一步将会一直阻塞
- Delivery delivery = consumer.nextDelivery();
- String msg = new String(delivery.getBody());
- System.out.println("收到消息:" + msg);
- }
- }
消息只能路由到一个 队列中。。。。
2.2 topic 交换机
direct 类型的交换机只能一对一的传递消息,而topic类型的交换机就牛逼了, 它支持糊糊匹配,啥意思呢?
在direct类型的交换机中,生产端和消息端的routingKey必须一样一样的,否则就不能拿到消息。 而topic类型就不一样了,譬如: 生产端的routingKey是 zheng.qin.feng,消息端的routingKey可以弄成以下这些都行:
zheng.#
#.feng
zheng.qin.*
总之,对于topic类型的交换机而言,一切都是看routingKey,如果消息端队列与交换机绑定时routingKey同生产端与交换机绑定的routingKey有一定龌蹉关系,那么消息最终就会投递到该队列中。
注意: 消息都是存储在队列中的,交换机只会转发消息,不会存储
# : 任意词匹配
* : 单词匹配
- /**
- * 生产端
- */
- public static void main(String[] args) throws Exception {
- //1 创建ConnectionFactory
- ConnectionFactory connectionFactory = new ConnectionFactory();
- connectionFactory.setHost("127.0.0.1");
- connectionFactory.setPort(5672);
- connectionFactory.setVirtualHost("/");
- //2 创建Connection
- Connection connection = connectionFactory.newConnection();
- //3 创建Channel
- Channel channel = connection.createChannel();
- //4 声明
- String exchangeName = "topic_exchange";
- String routingKey1 = "user.mmp";
- String routingKey2 = "user.exchange";
- String routingKey3 = "user.test";
- //5 发送
- String msg = "abc lfkdfjdlfjdlfkdlkfdlf";
- channel.basicPublish(exchangeName, routingKey1 , null , msg.getBytes());
- channel.basicPublish(exchangeName, routingKey2 , null , msg.getBytes());
- channel.basicPublish(exchangeName, routingKey3 , null , msg.getBytes());
- channel.close();
- connection.close();
- }
- /**
- * 消费者
- */
- public static void main(String[] args) throws Exception {
- ConnectionFactory connectionFactory = new ConnectionFactory() ;
- connectionFactory.setHost("127.0.0.1");
- connectionFactory.setPort(5672);
- connectionFactory.setVirtualHost("/");
- connectionFactory.setAutomaticRecoveryEnabled(true);
- connectionFactory.setNetworkRecoveryInterval(3000);
- Connection connection = connectionFactory.newConnection();
- Channel channel = connection.createChannel();
- //4 声明
- String exchangeName = "topic_exchange";
- String exchangeType = "topic";
- String queueName = "topic_queue";
- String routingKey = "user.*";
- // 1 声明交换机
- channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
- // 2 声明队列
- channel.queueDeclare(queueName, false, false, false, null);
- // 3 建立交换机和队列的绑定关系:
- channel.queueBind(queueName, exchangeName, routingKey);
- //durable 是否持久化消息
- QueueingConsumer consumer = new QueueingConsumer(channel);
- //参数:队列名称、是否自动ACK、Consumer
- channel.basicConsume(queueName, true, consumer);
- //循环获取消息
- while(true){
- //获取消息,如果没有消息,这一步将会一直阻塞
- Delivery delivery = consumer.nextDelivery();
- String msg = new String(delivery.getBody());
- System.out.println("收到消息:" + msg);
- }
- }
消息根据routingKey来决定路由到哪些队列中。。。。。
2.3 fanout交换机
这个没啥说的,跟routingKey木有关系,只要是绑定到fanout类型交换机上的队列,都能拿到消息。
简单的讲: 就是1 对多 的关系,, 比 topic类型的交换机还是滥情,毕竟topic交换机看不上丑女,fanout呢,是个女人都行。
- // 生产者
- public static void main(String[] args) throws Exception {
- //1 创建ConnectionFactory
- ConnectionFactory connectionFactory = new ConnectionFactory();
- connectionFactory.setHost("127.0.0.1");
- connectionFactory.setPort(5672);
- connectionFactory.setVirtualHost("/");
- //2 创建Connection
- Connection connection = connectionFactory.newConnection();
- //3 创建Channel
- Channel channel = connection.createChannel();
- //4 声明
- String exchangeName = "test_fanout_exchange";
- //5 发送
- for(int i = 0; i < 10; i ++) {
- String msg = "hahahah";
- channel.basicPublish(exchangeName, "", null , msg.getBytes());
- }
- channel.close();
- connection.close();
- }
- // 消息者
- public static void main(String[] args) throws Exception {
- ConnectionFactory connectionFactory = new ConnectionFactory() ;
- connectionFactory.setHost("127.0.0.1");
- connectionFactory.setPort(5672);
- connectionFactory.setVirtualHost("/");
- connectionFactory.setAutomaticRecoveryEnabled(true);
- connectionFactory.setNetworkRecoveryInterval(3000);
- Connection connection = connectionFactory.newConnection();
- Channel channel = connection.createChannel();
- //4 声明
- String exchangeName = "fanout_exchange";
- String exchangeType = "fanout";
- String queueName = "test_fanout_queue";
- String routingKey = ""; //不设置路由键,设置也可以,无所谓呀, 反正都行
- channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
- channel.queueDeclare(queueName, false, false, false, null);
- channel.queueBind(queueName, exchangeName, routingKey);
- //durable 是否持久化消息
- QueueingConsumer consumer = new QueueingConsumer(channel);
- //参数:队列名称、是否自动ACK、Consumer
- channel.basicConsume(queueName, true, consumer);
- //循环获取消息
- while(true){
- Delivery delivery = consumer.nextDelivery();
- String msg = new String(delivery.getBody());
- System.out.println("收到消息:" + msg);
- }
- }
尼玛,只要绑定到此交换机上的队列,都会被路由。。。。
RabbitMQ之交换机的更多相关文章
- 中间件系列三 RabbitMQ之交换机的四种类型和属性
概述本文介绍RabbitMQ中交换机类型和属性,主要内容如下: 交换机的作用交换机的类型:Direct exchange(直连交换机).Fanout exchange(扇型交换机).Topic exc ...
- RabbitMQ的交换机类型(三)
RabbitMQ的交换机类型共有四种,是根据其路由过程的不同而划分成的 分别是Direct Exchange(直连交换机), Fanout Exchange(扇型交换机), Topic Excha ...
- RabbitMQ中交换机的消息分发机制
RabbitMQ是一个消息代理,它接受和转发消息,是一个由 Erlang 语言开发的遵循AMQP协议的开源实现.在RabbitMQ中生产者不会将消息直接发送到队列当中,而是将消息直接发送到交换机(ex ...
- RabbitMQ学习笔记(4)----RabbitMQ Exchange(交换机)的使用
1. fanout模式 1.1 Publish/Subscribe(发布/订阅)结构图 上图表示一个消费者消费消息之后,不讲消息直接存储到队列,而是使用两个消费者各自声明一个队列,将各自的对应的队列与 ...
- RabbitMQ之交换机及spring整合
交换机 交换机属性: Name:交换机名称 Type:交换机类型 direct.topic.fanout.headers Durability:是否需要持久化,true为持久化 Auto Delete ...
- RabbitMQ 备份交换机(alternate-exchange)介绍
RabbitMQ之备份交换机(alternate-exchange) 1.备份交换器,AlternateExchange(AE) 备份交换器是为了实现没有路由到队列的消息,声明交换机的时候添加属性al ...
- RabbitMQ各种交换机类型Exchange Types介绍
最新版本的RabbitMQ有四种交换机类型,分别是Direct exchange.Fanout exchange.Topic exchange.Headers exchange. 一.Direct E ...
- RabbitMQ新建交换机、队列、交换机和队列绑定
新建交换机: 1.登录你要配置的交换机地址: 2.选择exchange,下拉选择add a new exchange 3.点击add exchange.完成 新建队列: 1.选择queues: 2.下 ...
- 认识RabbitMQ交换机模型
前言 RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工作虽然有用到,但是却没有形成很好的整体包括,主要是一些基础概念的认识,这里通过阅读<Rabbi ...
随机推荐
- LintCode之在O(1)时间复杂度删除链表
题目描述: 分析:因为题目要求不能用循环,而且只给了要删除的节点,并没有给链表.所以我无法取得要删除节点的前一个节点,只能在待删除的节点以及下一个节点上做文章.我的思路是:将待删除的节点的下一个节点的 ...
- openlayers筛选图层
很多时候需要筛选图层,例如选择交互(ol.interaction.Select). 图片来自官方:https://openlayers.org/en/v4.6.5/apidoc/ol.interact ...
- day03—JavaScript中DOM的Event事件方法
转行学开发,代码100天——2018-03-19 1.Event 对象 Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件通常与函数结合使用, ...
- php面向对象的重写与重载
重写: 就是当子类继承父类的一些方法后,子类又在其内部定义了相同的方法,则这个新定义的方法会覆盖继承而来的父类的方法,子类只能调用其内部定义的方法. 有以下几点要求: 1.当一个父类和子类有一个方法, ...
- SqlSession 内部运行
<深入浅出MyBatis技术原理与实战>p150页 SqlSession内部运行图 四大对象在流程中的操作. 1.准备sql.StatementHandler 的prepare方法进行sq ...
- Github建站笔记
下载Git 搜索"Git",在官网中根据系统版本下载,并双击打开,按默认已勾选组件点下一步; 勾选在Windows命令行窗口中使用Git: 使用推荐的OpenSSL库用于HTTPS ...
- c#访问webapi以及获取
提交post #region XML方式提交 public static void XML() { HttpWebRequest wReq = (HttpWebRe ...
- 机器学习实战_基于Scikit-Learn和Tensorflow读书笔记
第一部分 机器学习基础 第二部分 神经网络和深度学习 第9章 运行Tensorflow 分布式系统:分布式系统的定义是这个系统建立在网络的操作系统,具有高度的内聚性和透明性,它与网络的区别在于高层软件 ...
- python常用模块---collections、time、random、os、sys、序列号模块
collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdict. ...
- 20191114PHP图像绘制
<?phpob_clean();$img=imagecreate(400,400);$back=imagecolorallocate($img,200,200,100); $blue=image ...