总结一下几种ExchangeTypes。

之前写发布/订阅模式时第一次提到了exchange type。
即producer不是将消息直接放到队列中,而是先到exchange中,exchange主要用于控制消息到队列的路由,根据具体的exchange type将消息传给需要的队列或者直接废弃。
在这一篇中总结一下那些用到的exchange type。

一.Direct Exchange
direct exchange算是最基本的了。
direct exchange用于将带上routing key的消息传值拥有相同routing key的队列中。


当我们想用一个简单的标识符区别所有传入同一个exchange中的消息时direct exchange就非常合适。


private static String DIRECT_EXCHANGE = "DIRECT_EXCHAGNE"; static class FanoutProducer {
public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.newConnection();
Channel channel= connection.createChannel();; String content = "I miss the conversation";
channel.exchangeDeclare(DIRECT_EXCHANGE, ExchangeTypes.DIRECT);
channel.basicPublish(DIRECT_EXCHANGE, "alvez", null, content.getBytes());
}
} static class FanoutConsumer {
public static void main(String[] args) throws IOException, InterruptedException {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.newConnection();
Channel channel= connection.createChannel(); String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, DIRECT_EXCHANGE, "alvez"); QueueingConsumer consumer = new QueueingConsumer(channel);
String s = channel.basicConsume(queueName, true, consumer);
System.out.println(s);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
String routingKey = delivery.getEnvelope().getRoutingKey(); System.out.println("From:" + routingKey + "':'" + message + "'");
} }
  }

二.Fanout Exchange
fanout和routing key无关,它将消息无差别地(indiscriminately)传送给所有队列。

fanout exchange通常用于发布/订阅模式。
将消息传送给不同的队列,不同的队列对同一种消息采取不同的行为。
比如,现在有一个客户订单消息被三个队列接收,队列1完成该订单,队列2将订单写入日志,队列3将订单发给别的部门什么的。
比如下面的代码,消费者可以获得routing key并输出,但能否获取与routing key无关:


private static String FANOUT_EXCHANGE = "FANOUT_EXCHANGE"; static class DirectProducer {
public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.newConnection();
Channel channel= connection.createChannel();; String content = "I miss the conversation";
channel.exchangeDeclare(FANOUT_EXCHANGE, ExchangeTypes.FANOUT);
channel.basicPublish(FANOUT_EXCHANGE, "alvez", null, content.getBytes());
}
} static class DirectConsumer {
public static void main(String[] args) throws IOException, InterruptedException {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.newConnection();
Channel channel= connection.createChannel(); String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, FANOUT_EXCHANGE, ""); QueueingConsumer consumer = new QueueingConsumer(channel);
String s = channel.basicConsume(queueName, true, consumer);
System.out.println(s);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
String routingKey = delivery.getEnvelope().getRoutingKey(); System.out.println("From:" + routingKey + "':'" + message + "'");
} } }

三.Topic Exchange
如果根据topic exchange用法说明其特征的话反而更麻烦。
topic exchange正如其名,就是根据某种主题而不是特定的标题,也就是可以匹配routing key的一部分或者全部。
topic exchange的routing key可以有多个词组成,词用'.'分隔。
routing key中可以包括'*'或者'#','*'表示一个词,'#'表示0~N个词。

比如消息发布时routing key为"honda.civic.navy",
能接收消息的队列的routing key可以是"honda.civic.navy"或"*.civic.*"或"honda.#"或"#",
但不能是"honda.accord.navy"或"honda.accord.silver"或"*.accord.*"或"ford.#"。


private static String TOPIC_EXCHANGE = "TOPIC_EXCHAGNE"; static class TopicProducer {
public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.newConnection();
Channel channel= connection.createChannel();; String content = "I miss the conversation";
channel.exchangeDeclare(TOPIC_EXCHANGE, ExchangeTypes.TOPIC);
channel.basicPublish(TOPIC_EXCHANGE, "alvez.dep.FBI.map", null, content.getBytes());
}
} static class TopicConsumer {
public static void main(String[] args) throws IOException, InterruptedException {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.newConnection();
Channel channel= connection.createChannel(); String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, TOPIC_EXCHANGE, "alvez.#"); QueueingConsumer consumer = new QueueingConsumer(channel);
String s = channel.basicConsume(queueName, true, consumer);
System.out.println(s);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
String routingKey = delivery.getEnvelope().getRoutingKey(); System.out.println("From:" + routingKey + "':'" + message + "'");
} }
  }

四.Headers Exchange
即消息头和队列中声明的消息头匹配时可以通信,似乎不是很常用。
就可以定义多个条件进行匹配这一点来说,headers exchange和topic exchange有些相似。
有时候会给人"为什么会有这种东西?"的感觉,相比topic exchage有什么优势?
如果仅仅说"headers exchange是基于headers的,topic exchange是基于routing key的",这种回答没什么意义。

代码如下,可以看到producer和consumer的routing key是不同的,producer的header通过properties对象传输:


  private static String HEADERS_EXCHANGE = "HEADERS_EXCHANGE"; static class HeadersProducer {
public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel(); String content = "I miss the conversation";
channel.exchangeDeclare(HEADERS_EXCHANGE, ExchangeTypes.HEADERS);
AMQP.BasicProperties properties = new AMQP.BasicProperties();
Map<String,Object> map = new HashMap<>();
map.put("key1","val1");
properties.setHeaders(map); channel.basicPublish(HEADERS_EXCHANGE, "alvez", properties, content.getBytes()); }
} static class HeadersConsumer {
public static void main(String[] args) throws IOException, InterruptedException {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel(); String queueName = channel.queueDeclare().getQueue();
Map<String, Object> headers = new HashMap<>();
headers.put("key1","val1");
headers.put("key2","val2");
headers.put("key3","val3");
headers.put("key4","val4");
channel.queueBind(queueName, HEADERS_EXCHANGE, "",headers); QueueingConsumer consumer = new QueueingConsumer(channel);
String s = channel.basicConsume(queueName, true, consumer);
System.out.println(s);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
String routingKey = delivery.getEnvelope().getRoutingKey(); System.out.println("From:" + routingKey + "':'" + message + "'");
} } }

(ps:图不错,感谢图片作者。)

RabbitMQ - exchange的更多相关文章

  1. 5、RabbitMQ - Exchange之 fanout \ 【direct 关键字发送】 \ topic

    pytho系列之 RabbitMQ - Exchange几种模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 Rab ...

  2. RabbitMQ Exchange类型详解

    前言 在上一篇文章中,我们知道了RabbitMQ的消息流程如下: 但在具体的使用中,我们还需知道exchange的类型,因为不同的类型对应不同的队列和路由规则. 在rabbitmq中,exchange ...

  3. RabbitMQ Exchange详解以及Spring中Topic实战

    前言 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.消息中间件主要用于组件之间的解耦. 业务需求 ...

  4. rabbitmq exchange type

    This is the fourth installment to the series: RabbitMQ for Windows.  In thelast installment, we revi ...

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

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

  6. 四、RabbitMQ Exchange类型

    RabbitMQ整体上是一个生产者与消费者模型,主要负责接收.存储和转发消息.可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,RabbitMQ就好 ...

  7. Rabbitmq Exchange Type 说明

    Exchange在定义的时候是有类型的,以决定到底是哪些Queue符合条件,可以接收消息 fanout 所有bind到此exchange的queue都可以接收消息 direct 通过routingKe ...

  8. Behind RabbitMQ Exchange Types

    what's the underlying philosophy behind "exchange types"? In a word, it is all about imple ...

  9. RabbitMQ Exchange中的fanout类型

    fanout 多播 在之前都是使用direct直连类型的交换机,通过routingkey来决定把消息推到哪个queue中. 而fanout则是把拿到消息推到与之绑定的所有queue中. 分析业务,怎样 ...

随机推荐

  1. SQL Data Base 不装oracle客户端连接oracle服务端

    SQL Data Base  不装oracle客户端连接oracle服务端 一.直连: devart 二.拷贝dll: Oracle.DataAccess.dlloci.dllociw32.dll

  2. 【RabbitMQ学习记录】- 消息队列存储机制源码分析

    本文来自 网易云社区 . RabbitMQ在金融系统,OpenStack内部组件通信和通信领域应用广泛,它部署简单,管理界面内容丰富使用十分方便.笔者最近在研究RabbitMQ部署运维和代码架构,本篇 ...

  3. django中orm的简单操作

    数据库模型 from django.db import models # Create your models here. from django.db import models # Create ...

  4. “全栈2019”Java第六十六章:抽象类与接口详细对比

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. 从哈希结构去理解PHP数组

    php的数组实际上就是hash_table,无论是 数字索引数组array(1, 2, 3) 还是关联数组array(1 => 2, 2=> 4)等等. 一,这里的hash_table有几 ...

  6. 10分钟教你用Python玩转微信之好友性别比例统计分析

    01 前言+效果展示 想必,微信对于大家来说,是再熟悉不过的了.那么,大家想不想探索一下微信上的各种奥秘呢?今天,我们一起来简单分析一下微信上的好友性别比例吧~废话不多说,开始干活. 结果如下: 02 ...

  7. 2016级算法第五次上机-C.Bamboo和"Coco"

    1064 Bamboo和"Coco" 分析题意 每个亡灵至少一个花瓣,相邻的亡灵中思念值高的要获得的花瓣高(思念值相等是不需要花瓣一样多的).主要考贪心思路,为了使得花瓣总量最少, ...

  8. Scrapy 抓取股票行情

    安装scrapy会出现错误,我们选择anaconda3作为编译环境,搜索scrapy安装(有错误自查) 创建scrapy爬虫项目: 调出cmd,到相应目录:输入: scrapy startprojec ...

  9. Angular material mat-icon 资源参考_Maps

    ul,li>ol { margin-bottom: 0 } dt { font-weight: 700 } dd { margin: 0 1.5em 1.5em } img { height: ...

  10. 51nod 1812 树的双直径 题解【树形DP】【贪心】

    老了-稍微麻烦一点的树形DP都想不到了. 题目描述 给定一棵树,边权是整数 \(c_i\) ,找出两条不相交的链(没有公共点),使得链长的乘积最大(链长定义为这条链上所有边的权值之和,如果这条链只有 ...