RabbitMQ的Topics 通配符模式(Topic)
-
模式说明
- Topic 类型与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。只不过 Topic 类型Exchange 可以让队列在绑定 Routing key 的时候使用
通配符
! - Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
- 通配符规则:# 匹配一个或多个词,* 匹配不多不少恰好1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert,item.* 只能匹配 item.inser
- Topic 类型与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。只不过 Topic 类型Exchange 可以让队列在绑定 Routing key 的时候使用
-
Topics 通配符模式的图片
- 图解:
- 红色 Queue:绑定的是 usa.# ,因此凡是以 usa. 开头的 routing key 都会被匹配到
- 黄色 Queue:绑定的是 #.news ,因此凡是以 .news 结尾的 routing key 都会被匹配
-
其实这个Topics 通配符模式是Exchange常见类型之一的
Topic
-
代码编写生产者(Topic模式)步骤
- 创建工厂
- 设置参数
- 创建连接
- 创建channel(管道)
- 创建队列(这里只创建两个)
- 创建交换机
- 绑定队列和队列
- 发送消息
- 关闭连接
package com.yang;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer_Topics {
public static void main(String[] args) throws IOException, TimeoutException {
//1. 创建工厂
ConnectionFactory factory = new ConnectionFactory();
//2. 设置参数
factory.setHost("192.168.20.146");
factory.setPort(5672);
factory.setUsername("test");
factory.setPassword("test");
factory.setVirtualHost("/test");
//3. 创建连接
Connection connection = factory.newConnection();
//4. 创建管道
Channel channel = connection.createChannel();
//5. 创建队列
String queueName1 = "test_topic_queue1";
String queueName2 = "test_topic_queue2";
channel.queueDeclare(queueName1,true,false,false,null);
channel.queueDeclare(queueName2,true,false,false,null);
//6. 创建交换机
String exchangeName = "";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,true,false,false,null);
//7. 绑定队列和交换机
/*
queueBind(String queue, String exchange, String routingKey)
参数:
1. queue:队列名称
2. exchange:交换机名称
3. routingKey:路由键,绑定规则
如果交换机的类型为fanout ,routingKey设置为""
*/
// routing key 系统的名称.日志的级别。
//需求: 所有error级别的日志存入数据库,所有order系统的日志存入数据库
channel.queueBind(queueName1, exchangeName, "#.error");
channel.queueBind(queueName2, exchangeName, "order.*");
//8. 发送消息
String body = "日志信息:张三调用了findAll方法...日志级别:info...";
channel.basicPublish(exchangeName, "order.ss", null, body.getBytes());
//9. 释放资源
channel.close();
connection.close();
}
}
- 尝试执行之后(只有queueName2有,因为只有
order.*
符合)
- 发送别的消息
//8. 发送消息
String body = "日志信息:张三调用了delete方法...发生错误...error...";
channel.basicPublish(exchangeName, "order.error", null, body.getBytes());
- 尝试执行之后(只有queueName1和2都符合)
- 代码编写消费者(Topic模式)步骤(其实不管什么模式消费者基本都这样写,就改改一个地方而已)
- 创建工厂
- 设置参数
- 创建连接
- 创建管道channel
- 接收消息
package com.yang;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_Topics1 {
public static void main(String[] args) throws IOException, TimeoutException {
// 1. 创建工厂
ConnectionFactory factory = new ConnectionFactory();
// 2. 设置参数
factory.setHost("192.168.20.146");
factory.setPort(5672);
factory.setUsername("test");
factory.setPassword("test");
factory.setVirtualHost("/test");
//3. 创建连接
Connection connection = factory.newConnection();
// //4. 创建管道
Channel channel = connection.createChannel();
// 5. 接收消息
String queueName = "test_topic_queue1";
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body:"+new String(body));
System.out.println("将日志信息打印到控制台.....");
}
};
channel.basicConsume(queueName,true,consumer);
}
}
- 第二个队列只需要队列名改一下就行了!
String queueName = "test_topic_queue2";
- 两个的执行结果
-
Consumer_Topics1(队列:
test_topic_queue1
)
-
Consumer_Topics2(队列:
test_topic_queue2
)
-
- 和我们的需求一样:
所有error级别的日志存入数据库,所有order系统的日志存入数据库
-
小结
- Topic 主题模式可以实现 Pub/Sub 发布与订阅模式和 Routing 路由模式的功能,只是 Topic 在配置routing key 的时候可以使用通配符,显得更加灵活。
以上就是Topics 通配符模式的全部内容