http://blog.csdn.net/zhu_tianwei/article/details/40887775

参考:http://blog.csdn.NET/lmj623565791/article/details/37706355

direct类型的消息通过绑定键转发到队列,但是存在一些局限性:它不能够基于多重条件进行路由选择,有可能希望不仅根据日志的级别而且想根据日志的来源进行订阅,这就需要主题类型的转发器来实现。

发往主题类型的转发器的消息不能随意的设置选择键(routing_key),必须是由点隔开的一系列的标识符组成。标识符可以是任何东西,但是一般都与消息的某些特性相关。一些合法的选择键的例子:"stock.usd.nyse", "nyse.vmw","quick.orange.rabbit".你可以定义任何数量的标识符,上限为255个字节。
绑定键和选择键的形式一样。主题类型的转发器背后的逻辑和直接类型的转发器很类似:一个附带特殊的选择键将会被转发到绑定键与之匹配的队列中。需要注意的是:关于绑定键有两种特殊的情况。
*可以匹配一个标识符。
#可以匹配0个或多个标识符。

1.发送日志消息SendLogTopic,发送4个消息绑定不同的绑定键, "kernal.info", "cron.warning",  "auth.info", "kernel.critical"

  1. package cn.slimsmart.rabbitmq.demo.topic;
  2. import java.util.UUID;
  3. import com.rabbitmq.client.AMQP;
  4. import com.rabbitmq.client.Channel;
  5. import com.rabbitmq.client.Connection;
  6. import com.rabbitmq.client.ConnectionFactory;
  7. //发送消息端
  8. public class SendLogTopic {
  9. private static final String EXCHANGE_NAME = "topic_logs";
  10. public static void main(String[] args) throws Exception {
  11. // 创建连接和频道
  12. ConnectionFactory factory = new ConnectionFactory();
  13. factory.setHost("192.168.101.174");
  14. factory.setUsername("admin");
  15. factory.setPassword("admin");
  16. factory.setPort(AMQP.PROTOCOL.PORT);
  17. Connection connection = factory.newConnection();
  18. Channel channel = connection.createChannel();
  19. // 声明转发器
  20. channel.exchangeDeclare(EXCHANGE_NAME, "topic");
  21. //定义绑定键
  22. String[] routing_keys = new String[] { "kernal.info", "cron.warning",
  23. "auth.info", "kernel.critical" };
  24. for (String routing_key : routing_keys)
  25. {
  26. //发送4条不同绑定键的消息
  27. String msg = UUID.randomUUID().toString();
  28. channel.basicPublish(EXCHANGE_NAME, routing_key, null, msg
  29. .getBytes());
  30. System.out.println(" [x] Sent routingKey = "+routing_key+" ,msg = " + msg + ".");
  31. }
  32. channel.close();
  33. connection.close();
  34. }
  35. }

2.定义接收kernel.*消息的消费者

  1. package cn.slimsmart.rabbitmq.demo.topic;
  2. import com.rabbitmq.client.AMQP;
  3. import com.rabbitmq.client.Channel;
  4. import com.rabbitmq.client.Connection;
  5. import com.rabbitmq.client.ConnectionFactory;
  6. import com.rabbitmq.client.QueueingConsumer;
  7. //接收kernel.*消息
  8. public class ReceiveLogsTopicForKernel {
  9. private static final String EXCHANGE_NAME = "topic_logs";
  10. public static void main(String[] args) throws Exception {
  11. // 创建连接和频道
  12. ConnectionFactory factory = new ConnectionFactory();
  13. factory.setHost("192.168.101.174");
  14. factory.setUsername("admin");
  15. factory.setPassword("admin");
  16. factory.setPort(AMQP.PROTOCOL.PORT);
  17. Connection connection = factory.newConnection();
  18. Channel channel = connection.createChannel();
  19. // 声明转发器
  20. channel.exchangeDeclare(EXCHANGE_NAME, "topic");
  21. // 随机生成一个队列
  22. String queueName = channel.queueDeclare().getQueue();
  23. //接收所有与kernel相关的消息
  24. channel.queueBind(queueName, EXCHANGE_NAME, "kernel.*");
  25. System.out.println(" [*] Waiting for messages about kernel. To exit press CTRL+C");
  26. QueueingConsumer consumer = new QueueingConsumer(channel);
  27. channel.basicConsume(queueName, true, consumer);
  28. while (true)
  29. {
  30. QueueingConsumer.Delivery delivery = consumer.nextDelivery();
  31. String message = new String(delivery.getBody());
  32. String routingKey = delivery.getEnvelope().getRoutingKey();
  33. System.out.println(" [x] Received routingKey = " + routingKey
  34. + ",msg = " + message + ".");
  35. }
  36. }
  37. }

3.接收*.critical消息消费者

  1. package cn.slimsmart.rabbitmq.demo.topic;
  2. import com.rabbitmq.client.AMQP;
  3. import com.rabbitmq.client.Channel;
  4. import com.rabbitmq.client.Connection;
  5. import com.rabbitmq.client.ConnectionFactory;
  6. import com.rabbitmq.client.QueueingConsumer;
  7. //接收*.critical消息
  8. public class ReceiveLogsTopicForCritical {
  9. private static final String EXCHANGE_NAME = "topic_logs";
  10. public static void main(String[] args) throws Exception {
  11. // 创建连接和频道
  12. ConnectionFactory factory = new ConnectionFactory();
  13. factory.setHost("192.168.101.174");
  14. factory.setUsername("admin");
  15. factory.setPassword("admin");
  16. factory.setPort(AMQP.PROTOCOL.PORT);
  17. Connection connection = factory.newConnection();
  18. Channel channel = connection.createChannel();
  19. // 声明转发器
  20. channel.exchangeDeclare(EXCHANGE_NAME, "topic");
  21. // 随机生成一个队列
  22. String queueName = channel.queueDeclare().getQueue();
  23. // 接收所有与kernel相关的消息
  24. channel.queueBind(queueName, EXCHANGE_NAME, "*.critical");
  25. System.out
  26. .println(" [*] Waiting for critical messages. To exit press CTRL+C");
  27. QueueingConsumer consumer = new QueueingConsumer(channel);
  28. channel.basicConsume(queueName, true, consumer);
  29. while (true)
  30. {
  31. QueueingConsumer.Delivery delivery = consumer.nextDelivery();
  32. String message = new String(delivery.getBody());
  33. String routingKey = delivery.getEnvelope().getRoutingKey();
  34. System.out.println(" [x] Received routingKey = " + routingKey
  35. + ",msg = " + message + ".");
  36. }
  37. }
  38. }

启动2个消费者,再启动发送4类消息生产者。观察接收到的消息,都收到对应的消息。可以看出使用topic类型的转发器,成功实现了多重条件选择的订阅。

(转)RabbitMQ学习之主题topic(java)的更多相关文章

  1. (转) RabbitMQ学习之helloword(java)

    http://blog.csdn.net/zhu_tianwei/article/details/40835555 amqp-client:http://www.rabbitmq.com/java-c ...

  2. RabbitMQ入门(5)——主题(Topic)

    前面我们介绍了通过使用direct exchage,改善了fanout exchange只能进行虚拟广播的方式.尽管如此,直接交换也有自身的局限,它不能基于多个条件路由. 在我们的日志系统中,也许我们 ...

  3. (转) RabbitMQ学习之工作队列(java)

    http://blog.csdn.net/zhu_tianwei/article/details/40887717 参考:http://blog.csdn.NET/lmj623565791/artic ...

  4. rabbitMQ学习笔记(六) topic类型消息。

    上一节中使用了消息路由,消费者可以选择性的接收消息. 但是这样还是不够灵活. 比如某个消费者要订阅娱乐新闻消息 . 包括新浪.网易.腾讯的娱乐新闻.那么消费者就需要绑定三次,分别绑定这三个网站的消息类 ...

  5. (转)RabbitMQ学习之路由(java)

    http://blog.csdn.net/zhu_tianwei/article/details/40887755 参考:http://blog.csdn.NET/lmj623565791/artic ...

  6. RabbitMQ学习笔记二:Java实现RabbitMQ

    本地安装好RabbitMQ Server后,就可以在Java语言中使用RabbitMQ了. RabbitMQ是一个消息代理,从"生产者"接收消息并传递消息至"消费者&qu ...

  7. RabbitMQ学习笔记三:Java实现RabbitMQ之与Spring集成

    搭建好maven项目环境,加入RabbitMQ依赖包 <dependency> <groupId>org.springframework.amqp</groupId> ...

  8. RabbitMQ学习笔记五:RabbitMQ之优先级消息队列

    RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...

  9. RabbitMQ学习总结 第六篇:Topic类型的exchange

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

随机推荐

  1. 【VIP视频网站项目二】搭建爱奇艺优酷腾讯视频官网首页轮播图效果及实现原理分析

    这个是实现的效果,基本上轮播效果和主流网站的一致,但是我也在上面优化了一些效果, 可以在线预览效果:https://vip.52tech.tech/ 目前项目代码已经全部开源:项目地址:https:/ ...

  2. 七夕心形demo

    from turtle import * pensize(1) pencolor('red') fillcolor('pink') speed(5) up() goto(-30, 100) down( ...

  3. Python-jquery-datatable服务器分页.

    第一步: js初始化: part01:ajax设置 part02:语言设置 part03: 行列设置: part04: 具体渲染设置: 第二部: 服务端设置: 第一部分 获取固定表示: 第二部分 对数 ...

  4. java陷阱之spring事物管理导致锁无效

    模拟锁情况无效 1.创建一个表 SET NAMES utf8mb4; ; DROP TABLE IF EXISTS `demo`; CREATE TABLE `demo` ( `id` ) NOT N ...

  5. CODEVS——T 1297 硬币

    http://www.codevs.cn/problem/1297/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Descrip ...

  6. hdu - 4920 - Matrix multiplication(缓存优化+开挂)

    题意:求两个n x n的矩阵相乘后模3的结果,n <= 800. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4920 -->>呀呀 ...

  7. Android解决使用findViewById时须要对返回值进行类型转换问题的辅助类

    在我们的开发工作时,findViewById可能是用得最多的函数之中的一个.但它特别讨厌的地方就是我们常常须要对返回的view进行类型转换,输入麻烦.代码丑陋,比如曾经我们在Activity中找一些子 ...

  8. springmvc and maven

    使用Maven构建Spring MVC项目的简单示例 标签: mavenspringmvcspring 2013-09-29 12:40 42823人阅读 评论(8) 收藏 举报  分类: Maven ...

  9. 点击TButton后的执行OnClick和OnMouseDown两个事件的过程(其实是通过WM_COMMAND执行程序员的代码)

    问题的来源:在李维的<深入浅出VCL>一书中提到了点击TButton会触发WM_COMMAND消息,正是它真正执行了程序员的代码.也许是我比较笨,没有理解他说的含义.但是后来经过追踪代码和 ...

  10. 爬虫—分析Ajax爬取今日头条图片

    以今日头条为例分析Ajax请求抓取网页数据.本次抓取今日头条的街拍关键字对应的图片,并保存到本地 一,分析 打开今日头条主页,在搜索框中输入街拍二字,打开开发者工具,发现浏览器显示的数据不在其源码里面 ...