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. 洛谷P1060 开心的金明【dp】

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行&qu ...

  2. BALNUM - Balanced Numbers

    BALNUM - Balanced Numbers Time limit:123 ms Memory limit:1572864 kB Balanced numbers have been used ...

  3. Spring Boot 定时任务单线程和多线程

    Spring Boot 的定时任务: 第一种:把参数配置到.properties文件中: 代码: package com.accord.task; import java.text.SimpleDat ...

  4. Spring MVC自定义消息转换器(可解决Long类型数据传入前端精度丢失的问题)

    1.前言 对于Long 类型的数据,如果我们在Controller层通过@ResponseBody将返回数据自动转换成json时,不做任何处理,而直接传给前端的话,在Long长度大于17位时会出现精度 ...

  5. [bzoj3680]吊打XXX_模拟退火

    吊打XXX bzoj-3680 题目大意:在平面上给定n个点,每个点有一个权值.请在平面上找出一个点(不一定在这n个点内找)使得这个点到n个点的距离*权值最小,即求这n个点的重心. 注释:$1\le ...

  6. codevs 2460 树的统计

    2460 树的统计   题目描述 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I.             ...

  7. HDU 4530

    今天让人看不起了,话说好伤心,说我搞了ACM那么久都没获得拿得出手的奖.... 今晚爷爷我要狂刷2013腾讯马拉松的水题,奶奶滴,哈哈哈哈...T_T #include <iostream> ...

  8. POJ 1625

    什么鬼,真的是有负数的吗?我在字符加上了128才过了.dp[i][j],经过i步到达j状态的路径数.转移很容易了,建个trie图就可以,由前一步可连通到和更新即可. 另外,要用到大数和AC自动机DP ...

  9. PHP扩展开发--实验成功

    原文:http://kimi.it/496.html http://blog.csdn.net/u011957758/article/details/72234075 ---------------- ...

  10. NPOI文件导入操作

    using EntMSM.SmsDbContext; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserM ...