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. qinwoyige

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  2. 622FThe Sum of the k-th Powers

    题目大意 求$\sum_{i=1}^{n} i^k$ 分析 我们发现这是一个$k+1$次多项式 因此我们求出前$k+2$项然后插值即可 由于$x_i = i$ 因此公式里面的乘机可以通过预处理然后循环 ...

  3. RESTful三理解

    目录 目录 前言 Web应用的会话状态 Cookie 资源的表现形式 HATEOAS RESTful 资源 URI 前言 最近看了一篇很赞的RESTful博客,传送门:http://www.cnblo ...

  4. shell脚本一一项目3

    主题:批量创建100个用户并设置密码 脚本内容 user_list=$@user_file=./user.infofor USER in ${user_list};do if ! id $USER & ...

  5. python读写excle

    我们可以通过python的一些模块进行excle中用例的读取,或者导出数据到excle 目录 1.安装模块 2.读excle 3.写excle 1.安装模块 python中有第三方模块可以进行excl ...

  6. 关于Vue+iview的简单下拉框滚动加载

    话不多说,直接上代码,作用是下拉框内容无限滚动加载: Html: <FormItem style="position:relative" label="用户名:&q ...

  7. HDU 2512 一卡通大冒险 (第二类斯特林数)

    题目链接:HDU 2512 Problem Description 因为长期钻研算法, 无暇顾及个人问题,BUAA ACM/ICPC 训练小组的帅哥们大部分都是单身.某天,他们在机房商量一个绝妙的计划 ...

  8. LeetCode 112. Path Sum 动态演示

    给一个目标值,判断一棵树从根到叶子是否至少有一条路径加起来的和等于目标值 比较典型的深度优先算法. 引入一个全局变量bResult, 一旦找到一条,就不再搜索其他的了. class Solution ...

  9. Visio 2016自定义模具与形状

    Visio 2016自定义模具与形状 0. 什么是模具? 模具:一组形状的集合 1. 新建模具 打开Visio 2016,在空白的文件中选更多形状>>新建模具 2. 编辑模具 新建的模具已 ...

  10. 解决bug:sprongboot2整合shiro,swagger2页面样式加载不出来问题

    问题如题: 解决思路,把shiro拦截去掉之后发现swagger-ui.html页面接在的资源如下: 因此可以推断拦截器拦截了 "/swagger-resources" " ...