topic模式:exchange将routingKey和某个topic进行模糊匹配,队列需要绑定一个topic
- *:代表匹配一个单词
- #:代表匹配多个或零个单词
以上图为例:
Q1队列和交换机x绑定密钥为*.orange.*
;Q2队列和交换机x绑定密钥为*.*.rabbit
和lazy.#
- 如果我们发送消息的routingKey为
quick.orange.rabbit
那么它将被路由到Q1,Q2连个队列(匹配*.orange.*
和*.*.rabbit
) lazy.orange.elephant
那么它也将被路由到Q1,Q2队列(匹配lazy.#
和*.orange.*
)quick.orange.fox
只会进入Q1队列(匹配*.orange.*
)lazy.brown.fox.abc
只会进入Q2队列(匹配lazy.#
)lazy.pink.rabbit
只会进入Q2队列一次,即使匹配到两个队列quick.orange.male.rabbit
不会进入任何队列
通过上面讲解的例子应该了解topic模式以及其路由规则了,下面写代码测试下。
消费者:
package com.vivo.demo1.topic;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author:luzaichun
* @Date:2020/12/14
* @Time:23:17
**/
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
ConnectionFactory factory = new ConnectionFactory();
factory.setVirtualHost("/");
factory.setHost("192.168.3.7");
factory.setPort(5672);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare("topic_exchange","topic",false,false,null);
channel.queueDeclare("topic_queue",false,false,false,null);
channel.queueBind("topic_queue","topic_exchange","topic.#");
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
channel.basicConsume("topic_queue",true,queueingConsumer);
while (true){
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
System.out.println("接收到消息:"+new String(delivery.getBody()));
}
}
}
生产者:
package com.vivo.demo1.topic;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author:luzaichun
* @Date:2020/12/14
* @Time:23:22
**/
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setVirtualHost("/");
factory.setHost("192.168.3.7");
factory.setPort(5672);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.basicPublish("topic_exchange","topic",null,"这是一条消息,路由键为topi".getBytes());
channel.basicPublish("topic_exchange", "topic.abc", null, "这是一条消息,路由键为topic.abc".getBytes());
channel.basicPublish("topic_exchange", "topic.abc.123", null, "这是一条消息,路由键为topic.abc.123".getBytes());
channel.close();
connection.close();
}
}
可以看到routingKey为topic和topic.abc和topic.abc.123的消息都能路由到队列topic_queue上,说明#是可以匹配零个单词和多个单词的。
我们将队列和交换机绑定关系修改成topic.*
测试下(记得先解绑之前的"topic.#",可以在控制台操作
)
可以发现只能收到routingKey为topic.abc的消息,说明*只能匹配一个单词的情况