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. CentOS7.4上搭建rocketMQ集群

    一.rocketMQ集群部署方案优缺点对比: 多Master模式(2m-noslave) : 一个集群无Slave,全是Master,例如2个Master或者3个Master 优点:配置简单,单个Ma ...

  2. Linux启用ftp服务及连接

    虚拟机的系统是centos6.3 第一步.启动ftp service vsftpd restart 提示 vsftpd: 未被识别的服务 解决方法是升级vsftpd服务 yum install vsf ...

  3. 通过redis协议构建脏字过滤微服务

    下载 https://github.com/jonnywang/... 安装使用 mkdir -p /data/server/wordsFilter cd /data/server/wordsFilt ...

  4. PHP统计当前在线用户数实例

    HTML 我们在页面上放置一个显示当前在线人数的div#total以及一个用于展示访客地区分布的列表#onlinelist,默认我们在列表中放置一张与加载动画图片,后面我们用jQuery控制当鼠标滑向 ...

  5. 使用Layer完成图片放大功能

    序言:在写这个功能之前也用了zoom.js,zoom.js用起来简单引用js然后设置图片属性就可以放大.但是放大后的图片模糊.没有遮罩.在放大图片时其它图片布局会受到影响,当然如果觉得这些都是小问题的 ...

  6. android的数据与访问(2)-delphi xe7如何存取我的app配置参数文件?

    这种方法不推荐,因为该SharedPreference是android的方法.你想跨平台,在ios上就不能使用.建议还是用ini or xml.android因为读写该二种文件比较繁琐,所以推出自己简 ...

  7. jvm学习-垃圾回收算法(三)

     垃圾回收算法  引用计数法 比较古老的一种垃圾回收算法.在java的GC并没有采用 增加一个引用 引用+1 减少一个引用引用减一 每次清除引用为0的的对象 缺点:不能回收循环引用的垃圾对象 标记清除 ...

  8. orcale 单行函数之数字函数, 日期函数

    日期函数: 案例:

  9. orcale单行函数之字符函数

  10. 如何让 Windows 上的命令行工具更好用

    侯爵老师视频详解:如何让 Windows 上的命令行工具更好用 很多 Windows 用户在打开这个小黑窗时,都会情不自禁的感慨,「实在是太丑了--」 实际上如果你用的是 Windows 8 或 Wi ...