RabbitMQ 三种Exchange(fanout,direct,topic)模式

2018-07-05|来源:

RabbitMQ提供了四种Exchange:fanout,direct,topic,header, header模式在实际使用中较少,本文只对前三种模式进行比较。
性能排序:fanout > direct >> topic。比例大约为11:10:6


1、Fanout Exchange



任何发送到Fanout Exchange的消息都会被转发到与该Exchange绑定(Binding)的所有Queue上。

1、可以理解为路由表的模式
2、这种模式不需要RouteKey
3、这种模式需要提前将Exchange与Queue进行绑定,一个Exchange可以绑定多个Queue,一个Queue可以同多个Exchange进行绑定。
4、一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。
5、如果接受到消息的Exchange没有与任何Queue绑定,则消息会被抛弃。
6、Fanout交换机转发消息是最快的。
Channel channel = connection.createChannel();  
channel.exchangeDeclare("exchangeName", "fanout"); //direct fanout topic  
channel.queueDeclare("queueName");  
channel.queueBind("queueName", "exchangeName", "routingKey");  
channel.queueDeclare("queueName1");  
channel.queueBind("queueName1", "exchangeName", "routingKey1");  
byte[] messageBodyBytes = "hello world".getBytes();  
//路由键需要设置为空  
channel.basicPublish("exchangeName", "", MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);


2、 Direct Exchange

任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue。
1、处理路由键
2、需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “dog”,则只有被标记为“dog”的消息才被转发,不会转发dog.puppy,也不会转发dog.guard,只会转发dog。
3、一般情况可以使用rabbitMQ自带的Exchange:" "(该Exchange的名字为空字符串,下文称其为default Exchange)。
4、这种模式下不需要将Exchange进行任何绑定(binding)操作
5、消息传递时需要一个“RouteKey”,可以简单的理解为要发送到的队列名字。
6、如果vhost中不存在RouteKey中指定的队列名,则该消息会被抛弃。
Channel channel = connection.createChannel();  
channel.exchangeDeclare("exchangeName", "direct"); //direct fanout topic  
channel.queueDeclare("queueName");  
channel.queueBind("queueName", "exchangeName", "routingKey");  
byte[] messageBodyBytes = "hello world".getBytes();  
//需要绑定路由键  
channel.basicPublish("exchangeName", "routingKey", MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);


3、 Topic Exchange

任何发送到Topic Exchange的消息都会被转发到所有关心RouteKey中指定话题的Queue上
1、这种模式较为复杂,简单来说,就是每个队列都有其关心的主题,所有的消息都带有一个“标题”(RouteKey),Exchange会将消息转发到所有关注主题能与RouteKey模糊匹配的队列。
2、这种模式需要RouteKey,也许要提前绑定Exchange与Queue。
3、在进行绑定时,要提供一个该队列关心的主题,如“#.log.#”表示该队列关心所有涉及log的消息(一个RouteKey为”MQ.log.error”的消息会被转发到该队列)。
4、“#”表示0个或若干个关键字,“*”表示一个关键字。如“log.*”能与“log.warn”匹配,无法与“log.warn.timeout”匹配;但是“log.#”能与上述两者匹配。
5、同样,如果Exchange没有发现能够与RouteKey匹配的Queue,则会抛弃此消息。
Channel channel = connection.createChannel();  
channel.exchangeDeclare("exchangeName", "topic"); //direct fanout topic  
channel.queueDeclare("queueName");  
channel.queueBind("queueName", "exchangeName", "routingKey.*");  
byte[] messageBodyBytes = "hello world".getBytes();  
channel.basicPublish("exchangeName", "routingKey.one", MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);


书生整理于网络


相关问答

更多

rabbitmq的work模式怎么整合到spring中

abbitMQ主要有三种交换器:direct、fanout、topic direct就是一对一传输 fanout就是匹配传输 topic就是主题分发传输 还是看代码吧 maven构建:pom.xml [html] view plain copy <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLS ...

netty和rabbitmq的区别

netty和rabbitmq层次的问题: 我知道netty是tcp通信框架,rabbitmq是基于tcp通信封装的一种消息队列。如果包含套节字的话他们之间的关系层次是 socket/nio ---> netty ---> rabbitmq 这种,不知道我理解的有没有错误。 netty和rabbitmq 替换关系: 在不考虑数据解析序列化的前提下,单对单的,不涉及延时:能用netty的地方是不是可以用rabbitmq?能用rabbitmq的地方是不是可以使用netty+protobuf替换。

如何监控RabbitMQ的性能

测试 rabbitmq 的性能方法如下: 1、声明7个具有不同属性的queue,分别和名为test_exchage的exchange进行绑定(因为exchange为fanout类型,所以测试代码中的routing_key其实是不起作用的); 2、向exchange发送具有persistent属性的消息(delivery_mode=2); 3、创建7个消费者分别从上述7个queue中获取消息;

rabbitmq 控制界面怎么用

rabbitmq 编辑 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们。消 息传递指的是程序之间通过在消息中发送数据进行通...

rabbitmq控制台监控怎么开

rabbitmq 编辑 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。   应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们。

RabbitMQ 教程

相关文章

更多

最近更新

更多