rabbitmq学习(六) —— 主题
主题交换(Topic exchange)
使用 topic 类型的交换器,不能有任意的绑定键,它必须是由点隔开的一系列的标识符组成。标识符可以是任何东西,但通常它们指定与消息相关联的一些功能。其中,有几个有效的绑定键,例如 “stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”。可以有任何数量的标识符,最多可达 255 个字节。
topic 类型的交换器和 direct 类型的交换器很类似,一个特定路由的消息将被传递到与匹配的绑定键绑定的匹配的所有队列。关于绑定键有两种有两个重要的特殊情况:
*可以匹配一个标识符。# 可以匹配零个或多个标识符。

在这个例子中,我们将发送所有描述动物的消息。消息将使用由三个字(两个点)组成的绑定键发送。绑定键中的第一个字将描述速度,第二个颜色和第三个种类:“..”。其中, Q1 对所有的橙色动物感兴趣。而 Q2 想听听有关兔子的一切,以及关于懒惰动物的一切。
如果我们违反合同并发送一个或四个字的消息,如 “quick.orange.male.rabbit” 会发生什么?那么,这些消息将不会匹配任何绑定,并将被丢失。
topic 类型的交换器是强大的,可以实现其他类型的交换器。
当一个队列与“#”绑定绑定键时,它将接收所有消息,类似 fanout 类型的交换器。
当一个队列与 “*” 和 “#” 在绑定中不被使用时,类似 direct 类型的交换器。
案例实战
发送端
发送端,连接到 RabbitMQ,发送一条数据,然后退出。
public class EmitLogTopic {
private static final String EXCHANGE_NAME = "topic_logs";
private static final String[] LOG_LEVEL_ARR = {"dao.debug", "dao.info", "dao.error",
"service.debug", "service.info", "service.error",
"controller.debug", "controller.info", "controller.error"};
public static void main(String[] args) throws IOException, TimeoutException {
// 创建连接
ConnectionFactory factory = new ConnectionFactory();
// 设置 RabbitMQ 的主机名
factory.setHost("localhost");
// 创建一个连接
Connection connection = factory.newConnection();
// 创建一个通道
Channel channel = connection.createChannel();
// 指定一个交换器
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
// 发送消息
for (String severity : LOG_LEVEL_ARR) {
String message = "Liang-MSG log : [" +severity+ "]" + UUID.randomUUID().toString();
// 发布消息至交换器
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
}
// 关闭频道和连接
channel.close();
connection.close();
}
}
接受端
接受端,不断等待服务器推送消息,然后在控制台输出。
public class ReceiveLogsTopic {
private static final String EXCHANGE_NAME = "topic_logs";
private static final String[] LOG_LEVEL_ARR = {"#", "dao.error", "*.error", "dao.*", "service.#", "*.controller.#"};
public static void main(String[] args) throws IOException, TimeoutException {
// 创建连接
ConnectionFactory factory = new ConnectionFactory();
// 设置 RabbitMQ 的主机名
factory.setHost("localhost");
// 创建一个连接
Connection connection = factory.newConnection();
// 创建一个通道
Channel channel = connection.createChannel();
// 指定一个交换器
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
// 设置日志级别
int rand = new Random().nextInt(5);
String severity = LOG_LEVEL_ARR[rand];
// 创建一个非持久的、唯一的、自动删除的队列
String queueName = channel.queueDeclare().getQueue();
// 绑定交换器和队列
channel.queueBind(queueName, EXCHANGE_NAME, severity);
// 打印
System.out.println(" [*] LOG INFO : " + severity);
// 创建队列消费者
final Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
}
}
现在,做一个实验,我们开启三个 ReceiveLogsTopic 工作程序:ReceiveLogsTopic1、 ReceiveLogsTopic2 与 ReceiveLogsTopic3。
ReceiveLogsTopic1
[*] LOG INFO : dao.error
[x] Received 'Liang-MSG log : [dao.error]041cd8ba-df7d-4d20-a11f-ba21a0c2a02a'
ReceiveLogsTopic2
[*] LOG INFO : *.error
[x] Received 'Liang-MSG log : [dao.error]041cd8ba-df7d-4d20-a11f-ba21a0c2a02a'
[x] Received 'Liang-MSG log : [service.error]e3565f12-9782-4c22-a91c-f513f31b037d'
[x] Received 'Liang-MSG log : [controller.error]4436101a-3346-41f6-a9af-b8a4fbda451e'
ReceiveLogsTopic3
[*] LOG INFO : #
[x] Received 'Liang-MSG log : [dao.debug]4eb08245-2c05-490b-a5a5-2742cb70d831'
[x] Received 'Liang-MSG log : [dao.info]e9d4073b-1e61-4c6f-b531-ac42eaa346af'
[x] Received 'Liang-MSG log : [dao.error]041cd8ba-df7d-4d20-a11f-ba21a0c2a02a'
[x] Received 'Liang-MSG log : [service.debug]0ec84cbf-47ab-4813-a5db-e57d5e78830e'
[x] Received 'Liang-MSG log : [service.info]2e12e1b7-7a09-4eb7-8ad1-8e53f533121c'
[x] Received 'Liang-MSG log : [service.error]e3565f12-9782-4c22-a91c-f513f31b037d'
[x] Received 'Liang-MSG log : [controller.debug]94e5be72-15f6-496d-84f3-2a107bafc92b'
[x] Received 'Liang-MSG log : [controller.info]62bbe378-617d-4214-beb4-98cc53e73272'
[x] Received 'Liang-MSG log : [controller.error]4436101a-3346-41f6-a9af-b8a4fbda451e'
此时,ReceiveLogsTopic1 、ReceiveLogsTopic2 与 ReceiveLogsTopic3 同时收到了属于自己级别的消息。
我们发现,ReceiveLogsTopic1、ReceiveLogsTopic2、ReceiveLogsTopic3、ReceiveLogsTopic4同时收到了属于自己匹配的消息。尤其是ReceiveLogsTopic1 类似于 direct 类型的交换器,ReceiveLogsTopic3 类似于 fanout 类型的交换器。
源代码
rabbitmq学习(六) —— 主题的更多相关文章
- (转)RabbitMQ学习之主题topic(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887775 参考:http://blog.csdn.NET/lmj623565791/artic ...
- RabbitMQ学习总结 第六篇:Topic类型的exchange
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- RabbitMQ学习之:(六)Direct Exchange (转贴+我的评论)
From: http://lostechies.com/derekgreer/2012/04/02/rabbitmq-for-windows-direct-exchanges/ RabbitMQ fo ...
- 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ
鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...
- RabbitMQ学习总结 第三篇:工作队列Work Queue
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- RabbitMQ学习总结 第一篇:理论篇
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- RabbitMQ学习总结 第二篇:快速入门HelloWorld
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- RabbitMQ学习总结 第四篇:发布/订阅 Publish/Subscribe
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- RabbitMQ学习总结 第五篇:路由Routing
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
随机推荐
- 《剑指offer》— JavaScript(25)复杂链表的复制
复杂链表的复制 题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数 ...
- 口琴练习部分 - 多孔单音奏法 & 简单伴奏
多孔单音奏法(口含5个孔) 加入伴奏 理论知识 - 盖住 理论知识 - 松开 舌头一抬一合形成一个伴奏 高级一点的伴奏练习 正拍伴奏: 当要吹吸某一个音时,舌头先离开琴格,然后迅速盖上.
- python删除列表元素remove,pop,del
python删除列表元素 觉得有用的话,欢迎一起讨论相互学习~Follow Me remove 删除单个元素,删除首个符合条件的元素,按值删除,返回值为空 List_remove = [1, 2, 2 ...
- bzoj千题计划211:bzoj1996: [Hnoi2010]chorus 合唱队
http://www.lydsy.com/JudgeOnline/problem.php?id=1996 f[i][j][0/1] 表示已经排出队形中的[i,j],最后一个插入的人在[i,j]的i或j ...
- js拾遗: replace 替换参数
先来看一个简单的例子吧. var str = "123X321".replace("X", "$'"); 替换后的 str 是什么呢?是 & ...
- Javascript非构造函数的继承
一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese = { nation:'中国' }; 还有一个对象,叫做&qu ...
- Guava BiMap
BiMap主要的就是用于key,value的互相映射,获取相互的结果,还保证值value是唯一的,key相同覆盖原来值. 举例: BiMap<Integer, String> empIDN ...
- 什么是BS,BS和CS的区别有哪些
BS和CS的区别以及优缺点 C/S又称Client/Server或客户/服务器模式.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系统,如Oracle.Sybase.Informix或 ...
- Javascript - 预编译与函数词法作用域
预编译与函数词法作用域(Precompiled & Scoped) 预编译 Javascript脚本的宿主在执行代码之前对脚本做了预编译处理,比如浏览器对Js进行了预编译,编译器会扫描所有的声 ...
- nginx:在centos中自启动
参考网址:http://www.jb51.net/article/120545.htm # vi /etc/init.d/nginx #!/bin/sh # Name:nginx4comex # ng ...