> 文章列表 > RabbitMQ( 发布订阅模式 ==> TopicExchange)

RabbitMQ( 发布订阅模式 ==> TopicExchange)

RabbitMQ( 发布订阅模式 ==> TopicExchange)

本章目录:

  • 何为TopicExchange
  • TopicExchange的具体使用

一、何为TopicExchange

老样子,先看官方文档

在DirectExchange中,我们可以发送携带routingkey的消息到交换机中,交换机通过routingkey再去匹配一个或多个符合条件的队列

但是,发送消息时routingkey只能指定一个,它不能基于多个标准来进行路由

TopicExchange就是为了解决这一问题,其模式图如下

发送消息到topicExchange 时,不能指定一个任意的rountingkey,它必须为一个单词列表,比如:china.news这样的单词表。并且该列表最大长度为255个字节

它有点类似于directExchange,都需要使用特定routingkey发送消息并传递传递到所有使用匹配的绑定键绑定的队列,不同的是,它有两个通配符

  • *         可以代替一个单词。
  • #        可以代替零或多个单词

在上述的模式图中,Q1绑定了*.orange.*,Q2绑定了*.*.rabbit" 和 lazy.#,其中的含义为:

  • Q1匹配所有orange色的动物
  • Q2匹配所有兔子和以懒惰的动物

举几个例子:

routking=quick.orange.rabbit时,消息会被发送到Q1和Q2

routking=lazy.orange.elephantt时,消息也会被发送到Q1和Q2

routking=quick.orange.foxt时,消息只会被发送到Q1

routking=lazy.brown.foxt时,消息只会被发送到Q1

routking=quick.brown.fox时,消息只会被发送到Q1

当routing为orange或者quick.orange.new.rabbit时,因无法匹配到相应的队列,消息会被丢弃  

当routing为lazy.orange.new.rabbit时,及时单词列表长度为4,也会被投递到Q2。(因为#号代表匹配0个或多个单词)

二、 TopicExchange的具体使用

在消费者服务中,编写两个方法分别监听qA和qB。

    @RabbitListener(bindings = @QueueBinding(value = @Queue(name = "brrbaii.queueA"),exchange = @Exchange(name = "brrbaii.topic",type = ExchangeTypes.TOPIC),key = "china.*"))public void TA(String msg){System.out.println("queueA"+msg);}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "brrbaii.queueB"),exchange = @Exchange(name = "brrbaii.topic",type = ExchangeTypes.TOPIC),key = "#.weather"))public void TB(String msg){System.out.println("queueB"+msg);}

在publish内发布消息到TopicExchange 

我们预期的消息接收关系如下图

观察结果,完全匹配 

在看一看TopicExchange的特性

  • 当只使用#作为routingkey时,等同于fanoutExchange,像所有与之绑定的队列发送消息( 广播)
  • 当在routingkey里完全不适用*和#,它就像directExchange一样,只会将消息发送到完全匹配key的队列中

总结

Direct交换机与Topic交换机的差异?

  • Topic交换机接收的消息RoutingKey必须是多个单词,以 . 分割
  • Topic交换机与队列绑定时的bindingKey可以指定通配符
  • #:代表0个或多个词
  • *:代表1个词