topic的路由规则里使用【.】号分隔单词,使用【*】号匹配1个单词,使用【#】匹配多个.和多个*。

在下面的例子中:

logger.*可以匹配logger.error和logger.warning,但logger*.error只能匹配logger.error

logger#可以匹配到logger.error和logger.warning。

下面的例子使用topic接收警告、错误的日志,并根据匹配的路由规则发送给不同的Queue队列来处理的例子:

日志生产者SenderWithTopicExchange

  1. package com.yzl.test2;
  2.  
  3. import java.util.concurrent.CountDownLatch;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6.  
  7. import com.rabbitmq.client.Channel;
  8. import com.rabbitmq.client.Connection;
  9. import com.rabbitmq.client.ConnectionFactory;
  10.  
  11. /**
  12. * 使用topic交换器发送消息
  13. * 分为警告和错误2种日志
  14. * @author: yzl
  15. * @date: 2016-10-22
  16. */
  17. public class SenderWithTopicExchange {
  18. //交换器名称
  19. private static final String EXCHANGE_NAME = "myTopicExchange";
  20. //路由键的前缀
  21. private static final String BASE_ROUTING_KEY = "logger.";
  22.  
  23. public static void main(String[] args) throws Exception {
  24. //使用CountDownLatch控制2个线程一起运行
  25. final CountDownLatch cdl = new CountDownLatch(2);
  26. //连接到rabbitmq服务器
  27. ConnectionFactory factory = new ConnectionFactory();
  28. factory.setHost("localhost");
  29. Connection connection = factory.newConnection();
  30. //创建一个信道
  31. final Channel channel = connection.createChannel();
  32. //定义一个名字为topicExchange的topic类型的exchange
  33. channel.exchangeDeclare(EXCHANGE_NAME, "topic");
  34.  
  35. ExecutorService pool = Executors.newFixedThreadPool(2);
  36. pool.submit(new Runnable() {
  37. @Override
  38. public void run() {
  39. try {
  40. cdl.await();
  41. //发送警告日志,绑定路由键:logger.warning
  42. String warningMsg = "warning message is :";
  43. for(int i=1; i<800; i++){
  44. System.out.println("发送警告消息:" + warningMsg+i);
  45. channel.basicPublish(EXCHANGE_NAME, BASE_ROUTING_KEY + "warning", null, (warningMsg+i).getBytes());
  46. Thread.sleep(2000L);
  47. }
  48. } catch (Exception e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. });
  53. pool.submit(new Runnable() {
  54. @Override
  55. public void run() {
  56. try {
  57. cdl.await();
  58. //发送错误日志,绑定路由键:logger.error
  59. String errorMsg = "error message is :";
  60. for(int i=1; i<1000; i++){
  61. System.out.println("发送错误消息:" + errorMsg+i);
  62. channel.basicPublish(EXCHANGE_NAME, BASE_ROUTING_KEY + "error", null, (errorMsg+i).getBytes());
  63. Thread.sleep(2000L);
  64. }
  65. } catch (Exception e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. });
  70.  
  71. cdl.countDown();
  72. cdl.countDown();
  73. }
  74. }

消息消费者ReceiverWithTopicExchange

  1. package com.yzl.test2;
  2.  
  3. import java.io.IOException;
  4.  
  5. import com.rabbitmq.client.AMQP.BasicProperties;
  6. import com.rabbitmq.client.Channel;
  7. import com.rabbitmq.client.Connection;
  8. import com.rabbitmq.client.ConnectionFactory;
  9. import com.rabbitmq.client.DefaultConsumer;
  10. import com.rabbitmq.client.Envelope;
  11.  
  12. /**
  13. * 使用topic交换器接收消息
  14. *
  15. * @author: yzl
  16. * @date: 2016-10-22
  17. */
  18. public class ReceiverWithTopicExchange {
  19. // 交换器名称
  20. private static final String EXCHANGE_NAME = "myTopicExchange";
  21.  
  22. public static void main(String[] args) throws Exception {
  23. // 连接到rabbitmq服务器
  24. ConnectionFactory factory = new ConnectionFactory();
  25. factory.setHost("localhost");
  26. Connection connection = factory.newConnection();
  27. // 创建一个信道
  28. final Channel channel = connection.createChannel();
  29. // 定义一个名字为topicExchange的topic类型的exchange
  30. channel.exchangeDeclare(EXCHANGE_NAME, "topic");
  31.  
  32. //定义接收警告消息的队列
  33. channel.queueDeclare("warningQueue", false, false, false, null);
  34. //定义接收错误消息的队列
  35. channel.queueDeclare("errorQueue", false, false, false, null);
  36. //定义接收所有级别日志消息的队列
  37. channel.queueDeclare("allLoggerQueue", false, false, false, null);
  38.  
  39. //使用logger.warning路由键绑定myTopicExchange与warningQueue
  40. channel.queueBind("warningQueue", EXCHANGE_NAME, "logger.warning");
  41. //使用logger.error路由键绑定myTopicExchange与errorQueue
  42. channel.queueBind("errorQueue", EXCHANGE_NAME, "logger.error");
  43. //使用logger.*路由规则绑定myTopicExchange与allLoggerQueue
  44. channel.queueBind("allLoggerQueue", EXCHANGE_NAME, "logger.*");
  45.  
  46. //只处理警告日志,使用手动ack确认
  47. channel.basicConsume("warningQueue", false, new DefaultConsumer(channel){
  48. @Override
  49. public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
  50. throws IOException {
  51. String msg = new String(body);
  52. System.out.println("warningQueue accept a warning msg :" + msg);
  53. channel.basicAck(envelope.getDeliveryTag(), false);
  54. }
  55. });
  56. //只处理错误日志,使用手动ack确认
  57. channel.basicConsume("errorQueue", false, new DefaultConsumer(channel){
  58. @Override
  59. public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
  60. throws IOException {
  61. String msg = new String(body);
  62. System.out.println("errorQueue accept a error msg :" + msg);
  63. channel.basicAck(envelope.getDeliveryTag(), false);
  64. }
  65. });
  66. //处理警告和错误日志,使用手动ack确认
  67. channel.basicConsume("allLoggerQueue", false, new DefaultConsumer(channel){
  68. @Override
  69. public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
  70. throws IOException {
  71. String msg = new String(body);
  72. System.out.println("allLoggerQueue accept a logger msg :" + msg);
  73. channel.basicAck(envelope.getDeliveryTag(), false);
  74. }
  75. });
  76. }
  77. }

结果输出:

  1. 发送警告消息:warning message is :1
  2. 发送错误消息:error message is :1
  3. 发送警告消息:warning message is :2
  4. 发送错误消息:error message is :2
  5. 发送错误消息:error message is :3
  6. 发送警告消息:warning message is :3
  1. allLoggerQueue accept a logger msg :error message is :1
  2. allLoggerQueue accept a logger msg :warning message is :1
  3. errorQueue accept a error msg :error message is :1
  4. warningQueue accept a warning msg :warning message is :1
  5. warningQueue accept a warning msg :warning message is :2
  6. errorQueue accept a error msg :error message is :2
  7. allLoggerQueue accept a logger msg :warning message is :2
  8. allLoggerQueue accept a logger msg :error message is :2
  9. allLoggerQueue accept a logger msg :warning message is :3
  10. errorQueue accept a error msg :error message is :3
  11. warningQueue accept a warning msg :warning message is :3
  12. allLoggerQueue accept a logger msg :error message is :3

消息处理流程:

RabbitMQ学习笔记3-使用topic交换器的更多相关文章

  1. RabbitMQ学习笔记4-使用fanout交换器

    fanout交换器会把发送给它的所有消息发送给绑定在它上面的队列,起到广播一样的效果. 本里使用实际业务中常见的例子, 订单系统:创建订单,然后发送一个事件消息 积分系统:发送订单的积分奖励 短信平台 ...

  2. RabbitMQ学习笔记(五) Topic

    更多的问题 Direct Exchange帮助我们解决了分类发布与订阅消息的问题,但是Direct Exchange的问题是,它所使用的routingKey是一个简单字符串,这决定了它只能按照一个条件 ...

  3. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

  4. RabbitMQ学习笔记1-hello world

    安装过程略过,一搜一大把. rabbitmq管理控制台:http://localhost:15672/   默认账户:guest/guest RabbitMQ默认监听端口:5672 JAVA API地 ...

  5. 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

    在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...

  6. (转) Rabbitmq学习笔记

    详见原文: http://blog.csdn.net/shatty/article/details/9529463 Rabbitmq学习笔记

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

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

  8. 官网英文版学习——RabbitMQ学习笔记(七)Topic

    在上一篇中使用直接交换器改进了我们的系统,使得它能够有选择的进行接收消息,但它仍然有局限性——它不能基于多个条件进行路由.本节我们就进行能够基于多个条件进行路由的topics exchange学习. ...

  9. RabbitMQ学习笔记(六) RPC

    什么RPC? 这一段是从度娘摘抄的. RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的 ...

随机推荐

  1. 字符串和json之间的互相转化

    在Firefox,chrome,opera,safari,ie9,ie8等高级浏览器直接可以用JSON对象的stringify()和parse()方法. JSON.stringify(obj)将JSO ...

  2. 12 个 Web 设计师必备的 Bootstrap 工具

    转自:http://www.oschina.net/translate/12-best-bootstrap-tools-for-web-designers Bootstrap是一个非常棒的前端网站开发 ...

  3. REST API 安全设计指南

    0x01 REST API 简介 REST的全称是REpresentational State Transfer,表示表述性无状态传输,无需session,所以每次请求都得带上身份认证信息.rest是 ...

  4. codepage IMLangCodePages

      http://baike.baidu.com/link?url=78DSTGAri8dvHNLQ03rThSKieJqhFwFWL4sQMao6cfaRSOUWN88QVBwmSJPCZch0vf ...

  5. windows下使用体验更好的控制台——ConsoleZ

    转做前端开发以来,每天使用最频繁的工具就是控制台了,git提交代码要用,npm安装node包也要用,grunt task 也要用,可是系统自带的cmd太难用了, 那么问题就来了: "wind ...

  6. [ACM_图论] Fire Net (ZOJ 1002 带障碍棋盘布炮,互不攻击最大数量)

    Suppose that we have a square city with straight streets.  A map of a city is a square board with n ...

  7. ASP.NET MVC中三方登录: 微软、谷歌、Office365

    创建一个MVC的工程,在Startup.Auth.cs文件中,我们能看到这样的一些代码: 这其实是微软已经帮我们实现好的三方登录的接口,我们只需要创建相应的开发者账号,并在其中配置好跟我们应用程序相关 ...

  8. java.nio.BufferOverflowException. Check the Eclipse log for stack trace.

    这个错误错了几次,必须做个标记 解决方法非常的简单: 最新的19版本会在你的项目下建立一个依赖包 Android Dependencies,在eclipse中右键这个文件夹,在Build Path选项 ...

  9. VR快速发展下,从业者如何把握机会?

      美国科技博客VentureBeat周末刊登赛斯·沙赫纳(Seth Schachner)的文章,分析了在虚拟现实快速发展的情况下,业内所面临的机会,以及如何把握这些机会.   沙赫纳是资深的数字战略 ...

  10. paip.c3p0 nullpointexcept 配置文件根路径读取bug 解决

    paip.c3p0 nullpointexcept 配置文件根路径读取bug 解决 windows ok linux犯错误... 查看loging, 初始化的时候儿jdbcurl,user,pwd都是 ...