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之交换机的更多相关文章

  1. 中间件系列三 RabbitMQ之交换机的四种类型和属性

    概述本文介绍RabbitMQ中交换机类型和属性,主要内容如下: 交换机的作用交换机的类型:Direct exchange(直连交换机).Fanout exchange(扇型交换机).Topic exc ...

  2. RabbitMQ的交换机类型(三)

      RabbitMQ的交换机类型共有四种,是根据其路由过程的不同而划分成的 分别是Direct Exchange(直连交换机), Fanout Exchange(扇型交换机), Topic Excha ...

  3. RabbitMQ中交换机的消息分发机制

    RabbitMQ是一个消息代理,它接受和转发消息,是一个由 Erlang 语言开发的遵循AMQP协议的开源实现.在RabbitMQ中生产者不会将消息直接发送到队列当中,而是将消息直接发送到交换机(ex ...

  4. RabbitMQ学习笔记(4)----RabbitMQ Exchange(交换机)的使用

    1. fanout模式 1.1 Publish/Subscribe(发布/订阅)结构图 上图表示一个消费者消费消息之后,不讲消息直接存储到队列,而是使用两个消费者各自声明一个队列,将各自的对应的队列与 ...

  5. RabbitMQ之交换机及spring整合

    交换机 交换机属性: Name:交换机名称 Type:交换机类型 direct.topic.fanout.headers Durability:是否需要持久化,true为持久化 Auto Delete ...

  6. RabbitMQ 备份交换机(alternate-exchange)介绍

    RabbitMQ之备份交换机(alternate-exchange) 1.备份交换器,AlternateExchange(AE) 备份交换器是为了实现没有路由到队列的消息,声明交换机的时候添加属性al ...

  7. RabbitMQ各种交换机类型Exchange Types介绍

    最新版本的RabbitMQ有四种交换机类型,分别是Direct exchange.Fanout exchange.Topic exchange.Headers exchange. 一.Direct E ...

  8. RabbitMQ新建交换机、队列、交换机和队列绑定

    新建交换机: 1.登录你要配置的交换机地址: 2.选择exchange,下拉选择add a new exchange 3.点击add exchange.完成 新建队列: 1.选择queues: 2.下 ...

  9. 认识RabbitMQ交换机模型

    前言 RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工作虽然有用到,但是却没有形成很好的整体包括,主要是一些基础概念的认识,这里通过阅读<Rabbi ...

随机推荐

  1. ORACLE Physical Standby DG搭建

    主库: 一:强制force logging: alter database force logging; 二:开启主库的归档模式 三:主库添加standby redo log,比redo日志组多一组: ...

  2. Log4j appender、layout

    appender输出类型配置 layout日志信息格式 Threshold属性指定输出等级 Append属性指定是否追加内容 (1)appender输出类型配置 Log4j官方的appender给出了 ...

  3. PHP-执行外部程序

    备份 / 恢复数据库 exec - 执行一个外部程序(在 php 文件所在目录进行执行) 很久以前写的,很多方法是项目中的直接复制粘体用不了,只能提供下思路. 用到执行外部程序的就这一句: exec( ...

  4. Java常用工具——java包装类

    一.包装类和基本数据类型 装箱:基本数据类型——包装类 拆箱:包装类——基本数据类型 package com.imooc.wrap; public class WrapTestOne { public ...

  5. Postman 测试Xfire webservice

    权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u013177381/article/det ...

  6. HTML表格<tr>行距调整

    CSS文件中: .myTable tr{     display:block; /*将tr设置为块体元素*/     margin-bottom:5px;}

  7. Vulnhub渗透测试练习(一) ----------Breach1.0

    教程网址 https://www.freebuf.com/articles/system/171318.html 学习经验总结 1.使用jre的bin目录下的keytool命令来输入秘钥库口令进而获取 ...

  8. MySQL数据库忘记密码如何重新设置?

    前 言当我们忘记了MySQL数据库密码后,该如何重新进行设置? 操作步骤步骤1:cmd打开命名窗口 步骤2:关闭正在运行的MySQL服务(命令:net stop mysql)(如果:此时MySQL正在 ...

  9. golang简介

    GO语言是Google于2009年推出的一门新的系统编程语言 特点: 静态编译 垃圾回收 简洁的符号和语法 平坦的类型系统 基于CSP的并发模型 高效简单的工具链 丰富的标准库 为什么选择go语言 编 ...

  10. [Interview] Bubble sort using singly-linked list

    Question : Bubble sort using singly-linked list 群暉面試題 Idea :  在linked list 交換node與node時, 我們會想用換*next ...