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 ...
随机推荐
- ORA-01578: ORACLE 数据块损坏 (文件号 10, 块号 57896)ORA-01110: 数据文件 10: '/data/oradata/prod35.dbf'
https://community.oracle.com/thread/3540795 概述 ------------- 数据库坏块(corruption) 的类型可以按照坏块所属对象的不同,分为用户 ...
- thread_process_action
import math import random import re import sys import threading from time import ctime, sleep from l ...
- Mac定制终端:iTerm2 + zsh + powerline
原始界面: 配置后的界面: 安装iTerm2 可以直接去官网下载:https://www.iterm2.com/ 下载后直接安装即可 安装主题 所有主题:https://iterm2color ...
- ArrayList 源码解读
ArrayList 源码解读 基于JDk 1.7.0_80 public class ArrayList<E> extends AbstractList<E> impl ...
- 涛涛的小马甲 Android之Handler机制
首先需要了解一个基本的概念ANR:Application not response 即应用程序无响应,也就是俗话说的死机. 出现Anr的原因是: 主线程需要做很多重要的事情,响应点击事件,更新UI如果 ...
- MySQL 查询性能优化 - EXPLAIN 命令
查询优化的官方文档在 这里. EXPLAIN 的输出格式 译文 1. MySQL 架构 1.1 MySQL 的简化架构 MySQL 可以简单的分为三层:连接层.服务层.存储引擎层.其中服务层包含了 M ...
- 爬虫(十一)—— 请求库(三)pypeteer请求库
曾经使用模拟浏览器操作(selenium + webdriver)来写爬虫,但是稍微有点反爬的网站都会对selenium和webdriver进行识别,网站只需要在前端js添加一下判断脚本,很容易就可以 ...
- Ubuntu12.04安装MariaDB并修改字符集为UTF-8
其实按照MariaDB官网的步骤来安装MariaDB特别的简单,只要按照步骤来做,很容易就搞定了. 首先,到MariaDB官网: https://downloads.mariadb.org/maria ...
- 2019 最新 Java 核心技术教程,都在这了!
Java技术栈 www.javastack.cn 优秀的Java技术公众号 以下是Java技术栈微信公众号发布的所有关于 Java 的技术干货,会从以下几个方面汇总,本文会长期更新. Java 基础篇 ...
- kmp(循环节)
Cyclic Nacklace Problem Description CC always becomes very depressed at the end of this month, he ha ...