RabbitMQ常用的交换器类型有fanout、direct、topic、headers这四种。AMQP协议里还提到另外两种类型:system和自定义,这里不予描述。
fanout
它会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。
direct
direct类型的交换器路由规则也很简单,它会把消息路由到那些BindingKey和RoutingKey完全匹配的队列中。
以下图为例,交换器的类型为direct,如果我们发送一条消息,并在发送消息的时候设置路由键为“warning”,则消息会路由到Queue1和Queue2, 如下图所示:
如果在发送消息的时候设置路由键为“info”或者“debug”,消息只会路由到Queue2。如果以其他的路由键发送消息,则消息不会路由到这两个队列中。
topic
前面讲到direct类型的交换器路由规则是完全匹配BindingKey和RoutingKey,但是这种严格的匹配方式在很多情况下不能满足实际业务的需求。topic类型的交换器在匹配规则上进行了扩展,它与direct类型的交换器相似,也是将消息路由到BindingKey和RoutingKey相匹配的队列中,但这里的匹配规则有些不同,它约定:
(一)RoutingKey为一个点好“.”分隔的字符串(被点号“.”分隔开的每一段独立的字符串称为一个单词),如“com.rabbitmq.client”、“com.hidden.client”。
(二)BindingKey和RoutingKey一样也是点号“.”分隔的字符串。
(三)BindingKey中可以存在两种特殊字符串“*”和“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配零个或多个单词。
以下图的配置为例:
1) 路由键为“com.rabbitmq.client”的消息会同时路由到Queue1和Queue2。
2) 路由键为“com.hidden.client”的消息只会路由到Queue2中。
3) 路由键为“com.hidden.demo”的消息只会路由到Queue2中。
4) 路由键为“java.rabbitmq.demo”的消息只会路由到Queue1中。
5) 路由键为“java.util.concurrent”的消息将会被丢弃或者返回给生产者(需要设置mandatory参数),因为它没有匹配任何路由键。
headers
headers类型的交换器不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。在绑定队列和交换器时指定一组键值对,当发送消息到交换器时,RabbitMQ会获取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果完全匹配则消息会路由到该队列,否则不会路由到该队列。headers类型的交换器性能会很差,而且也不实用,基本上不会看到它的存在。