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. swift-UITableView的基本使用

    废话不多说了,直接贴我今天写的代码吧:如果新手有什么不懂的,可以发我邮箱. // //  singleInfo.swift            个人信息 //  Housekeeper // //  ...

  2. centos最小化系统安装VMware tool

    1.先执行命令创建环境 yum -y install update yum -y install gcc kernel-headers kernel-devel 2.然后重启reboot 3.挂载,解 ...

  3. 在做公司项目是时,昨天晚上还好的,但是第二天启动tomcat发现tomcat启动了,但是没把项目启动起来

    1.问题:在做公司项目是时,昨天晚上还好的,但是第二天启动tomcat发现tomcat启动了,但是没把项目启动起来 2.问题排除: 1)昨天晚上还好着呢,并且没改动代码,排除代码问题.日志中无报错信息 ...

  4. Java Web学习总结(19)——web.xml配置详解

    1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Servl ...

  5. 0608MySQL备份与恢复之percona-xtrabackup软件的使用【基础】

    转自http://blog.csdn.net/justdb/article/details/17054579 一 使用percona-xtrabackup的原因 在前面,我们讲到MySQL冷备.热备. ...

  6. 使用 Redis及其产品定位

    实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题: ...

  7. Linux系统下怎样配置SSH?怎样开启SSH?

    SSH作为Linux远程连接重要的方式,怎样配置安装linux系统的SSH服务.怎样开启SSH?以下来看看吧(本例为centos系统演示怎样开启SSH服务) 1.登陆linux系统,打开终端命令.输入 ...

  8. Android SQLite服务--创建、增删改查

    <pre name="code" class="java">import android.content.Context; import andro ...

  9. GNU TeXmacs 1.99.8 发布,所见即所得科学编辑器(看看老实的GUI)

    GNU TeXmacs 1.99.8 已发布,这是一个支持各种数学公式的所见即所得编辑器,可以用来编辑文本.图形.数学.交互内容,它的界面非常友好,并且内置高质量的排版引擎. 更新内容: bug 修复 ...

  10. Working with macro signatures

    https://docs.kentico.com/k11/macro-expressions/troubleshooting-macros/working-with-macro-signatures ...