本章目录:
- 何为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个词