RabbitMQ之Exchange
来源:互联网 发布:对付淘宝卖家的狠招 编辑:程序博客网 时间:2024/05/26 15:57
rabbitMQ消息模型的核心思想是生产者不会将消息直接发送给队列。生产者通常不知道消息将会被哪些消费者接收,按照刚开始里介绍的rabbitMQ中所画的,生产者不是直接将消息发送给Queue么认识会交给Exchange,所以需要定义Exchange的消息分发模型来实现消息的分发,即发布者/订阅者模式,用这种模型来实现生产者与消费者之间的解耦。
那我们之前的例子中为什么只定义了一个队列,而没有定义Exchange,起不是违背了生产者不会将消息直接发送给队列的核心思想?我们来回顾一下之前生产者发布消息时的代码:
channel.basicPublish("", queueName, MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());
第一个参数是空字符串,其实这个参数就是Exchange,这里定义了一个默认的Exchange。
如果用空字符串去申明一个exchange,那么系统就会使用"amq.direct"这个exchange。我们在创建一个queue的时候,默认的都会有一个和新建queue同名的routingKey绑定到这个默认的exchange上去,所以我们之前第二个参数里我们都是写的queueName。
Exchange
关于exchange,生产者只能发送消息到一个交换组件中(Exchange),exchange是一个很简单的东西,一方面它接收来自生产者的消息,另外一方面它将把来自生产者的消息放入到队列中,exchange必须知道怎么接收一个消息,而且接收的消息应该被添加到一个特定的队列?还是多个队列中?或者接收的消息被丢弃,这个规则被exchange类型所定义。
Exchange有如下几种定义类型:direct(直接)、topic(主题)、headers(标题)和fanout,可以通过命令 rabbitmqctl list_exchanges查看
以下为常用的三种类型:direct、topic、headers
Direct Exchange
任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue。
1.一般情况可以使用rabbitMQ自带的Exchange:“”(该Exchange的名字为空字符串,之前称其为default Exchange)。
2.这种模式下不需要将Exchange进行任何绑定(binding)操作
3.消息传递时需要一个“RouteKey”,而且要求消息与这一路由键完全匹配,可以简单的理解为要发送到的队列名字。
4.如果vhost中不存在RouteKey中指定的队列名,则该消息会被抛弃。
简单的关键代码示例:
生产者:
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
channel.basicPublish(EXCHANGE_NAME,"routingKey",MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
注释:EXCHANGE_NAME可以为空字符串””。
消费者:
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, EXCHANGE_NAME, "routingKey");
Fanout Exchange
任何发送到Fanout Exchange的消息都会被转发到与该Exchange绑定(Binding)的所有Queue上。
1.可以理解为路由表的模式(通过exchange把消息路由到队列中)
2.这种模式不需要RouteKey
3.这种模式需要提前将Exchange与Queue进行绑定,一个Exchange可以绑定多个Queue,一个Queue可以同多个Exchange进行绑定。
4.如果接受到消息的Exchange没有与任何Queue绑定,则消息会被抛弃。
简单的关键代码示例:
生产者:
//fanout表示消息将以广播的形式分发给多个消费者
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
channel.basicPublish(EXCHANGE_NAME,"",MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
消费者:
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, EXCHANGE_NAME, "");
Topic Exchange
任何发送到Topic Exchange的消息都会被转发到所有关心RouteKey中指定主题的队列(Queue)上
1.这种模式较为复杂,简单来说,就是每个队列都有其关心的主题,所有的消息都带有一个“标题”(RouteKey),Exchange会将消息转发到所有关注主题能与RouteKey模糊匹配的队列。
2.这种模式需要RouteKey,也许要提前绑定Exchange与Queue。
3.在进行绑定时,要提供一个该队列关心的主题,如“#.log.#”表示该队列关心所有涉及log的消息。
4.“#”表示0个或若干个关键字,“*”表示一个关键字。如“log.*”能与“log.warn”匹配,无法与“log.warn.timeout”匹配;但是“log.#”能与上述两者匹配。
5.如果Exchange没有发现能够与RouteKey匹配的Queue,则会抛弃此消息。
简单的关键代码示例:
生产者:
channel.exchangeDeclare(EXCHANGE_NAME,"topic");
String[] keys ={"USA.weather.1","China.weather.1","USA.people.1","China.people.1"};
for(String key:keys){
String msg = key+":消息";
channel.basicPublish(EXCHANGE_NAME,key,null,msg.getBytes());
}
消费者:
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
String queue = channel.queueDeclare().getQueue();
String key ="*.weather.*";
channel.queueBind(queue, EXCHANGE_NAME, key);
之前包括本节讲到的代码示例链接:http://download.csdn.net/detail/xiaoyatouvsanan/7571743
- RabbitMQ之Exchange
- RabbitMQ学习之exchange总结
- RabbitMQ Exchange模式之Direct
- RabbitMQ Exchange模式之Topic
- RabbitMQ Exchange模式之Fanout
- RabbitMQ exchange
- pytho系列之 RabbitMQ - Exchange几种模式
- RabbitMQ四种Exchange类型之Fanout (Java)
- RabbitMQ四种Exchange类型之Fanout (Erlang)
- RabbitMQ四种Exchange类型之Direct (Java)
- RabbitMQ四种Exchange类型之Direct (Erlang)
- RabbitMQ四种Exchange类型之Topic (Java)
- RabbitMQ四种Exchange类型之Topic(Erlang)
- RabbitMQ四种Exchange类型之Headers(Java)
- RabbitMQ四种Exchange类型之Headers(Erlang)
- Spring Boot 整合 RabbitMQ 之 Fanout Exchange模式 (三)
- RabbitMQ的Exchange 模式之topic(主题模式)
- RabbitMQ的Exchange 模式之direct(指定模式)
- ios网络学习------5 json格式数据的请求处理
- 面向对象的三大特性(封装、继承和多态)
- C++ class(类)
- 如何建立npm私库
- C++和C的联系与区别
- RabbitMQ之Exchange
- 【Unity 3D】学习笔记二十三:unity游戏脚本(三)
- WWDC英语演讲
- 《如何阅读一本书》读后
- 归并排序的内存使用,
- sql 查询所有数据库、表名、表字段总结
- 插入排序--就差希尔,暂时写不出,日后更新
- 数字电路设计之低功耗设计方法一:bus总线翻转
- activity的任务栈