Topics

  • In the previous tutorial we improved our logging system. Instead of using a fanout exchange only capable of dummy broadcasting,we used a direct one ,and gained a possibility of selectively receiving the logs.
  • Although using the direct exchange improved our system,it still has limitations - it can't do routing based on multiple criteria.
  • In our logging system we might want to subscribe to not only logs based on severity,but also based on the source which emitted the log.You might know this concept from the syslog unix tool,which routes logs based on both severity and facility.
  • That would give us a lot of flexibility - we may want to listen to just critical error coming from 'cron' but also all logs from 'kern'.
  • To implement that in our logging system we need to learn about a more complex topic exchange.

Topic exchange

  • Message sent to a topic exchange can't have an arbitrary routing_key - it must be a list of words,delimited by dots.The words can be anything, but usually they specify some features connected to the message.A few valid routing key examples:"stock.usd.nyse","nyse.vmw","quick.orange.rabbit".There can be as many words in the routing key as you like, up to the limit of 255 bytes.

  • The binding key must also be in the same form.The logic behind the topic exchange is similar to a direct one - a message sent with a particular routing key will be delivered to all the queues that are bound with a matching binding key.However there are two important special cases for binding keys:

    • (star) can substitute for exactly one word.
    • (hash) can substitute for zero or more words.
  • In this example,we're going to send message which all describe animals.The messages will be sent with a routing key that consists of three words(two dots).The first word in the routing key will describe speed,second a colour and third a species:"..".

  • We created three bindings: Q1 is bound with binding key ".orange." and Q2 with "..rabbit" and "lazy.#".

  • These bindings can be summarised as:

    • Q1 is interested in all the orange animals.
    • Q2 wants to hear everything about rabbits, and everything about lazy animals.
  • A message with a routing key set to "quick.orange.rabbit" will be delivered to both queues. Message "lazy.orange.elephant" also will go to both of them. On the other hand "quick.orange.fox" will only go to the first queue, and "lazy.brown.fox" only to the second. "lazy.pink.rabbit" will be delivered to the second queue only once, even though it matches two bindings. "quick.brown.fox" doesn't match any binding so it will be discarded.

  • What happens if we break our contract and send a message with one or four words, like "orange" or "quick.orange.male.rabbit"? Well, these messages won't match any bindings and will be lost.

  • On the other hand "lazy.orange.male.rabbit", even though it has four words, will match the last binding and will be delivered to the second queue.

Code

  •   public class EmitLogTopic {
    private static Log log = LogFactory.getLog(EmitLogTopic.class);
    private static final String EXCHANGE_NAME="topic_logs";
    public static void main(String[] argv)
    {
    ConnectionFactory connFactory = new ConnectionFactory();
    connFactory.setHost("localhost");
    Connection conn=null;
    Channel channel=null;
    try {
    conn=connFactory.newConnection();
    channel=conn.createChannel();
    channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
    //String[] severity={"info.#","warning.*","*.error.*"};
    String message="info.hello,world";
    channel.basicPublish(EXCHANGE_NAME,"info.fasfa.fasfas.fasfa",null,message.getBytes());//消息以info开头
    System.out.println("sent:"+message);
    /*for(String s:severity)
    {
    channel.basicPublish(EXCHANGE_NAME,s,null,message.getBytes());
    System.out.println("sent:"+s+" "+message);
    }*/ } catch (IOException e) {
    log.error(e);
    } catch (TimeoutException e) {
    log.error(e);
    } finally {
    if (channel!=null)
    {
    try {
    channel.close();
    } catch (IOException e) {
    log.error(e);
    } catch (TimeoutException e) {
    log.error(e);
    }
    }
    if (conn!=null)
    {
    try {
    conn.close();
    } catch (IOException e) {
    log.error(e);
    }
    }
    } }
    }
    public class ReceiveLogTopic {
    private static Log log= LogFactory.getLog(ReceiveLogTopic.class);
    private static final String EXCHANGE_NAME="topic_logs";
    public static void main(String[] argv)
    {
    ConnectionFactory connFactory = new ConnectionFactory();
    connFactory.setHost("localhost");
    /*Connection conn=null;
    Channel channel=null;*/
    try {
    final Connection conn=connFactory.newConnection();
    final Channel channel=conn.createChannel();
    channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
    String queueName=channel.queueDeclare().getQueue(); String[] severity={"info.#","warning.*","*.error.*"};
    /*for (String s:severity)
    {
    channel.queueBind(queueName,EXCHANGE_NAME,s);
    }*/
    channel.queueBind(queueName,EXCHANGE_NAME,"info.#");//消费者关注关于info的消息,消息以info开头
    Consumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    String message=new String(body,"UTF-8");
    System.out.println("receive:"+envelope.getRoutingKey()+" "+message);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    log.error(e);
    }finally {
    channel.basicAck(envelope.getDeliveryTag(),false);
    }
    }
    };
    channel.basicConsume(queueName,false,consumer);
    } catch (IOException e) {
    log.error(e);
    } catch (TimeoutException e) {
    log.error(e);
    } finally {
    }
    }
    }

Summary

  • 消费者通过使用通配符关注一个有关的话题,当符合适配条件的消息传递路由器时,就会被分发到该监听队列,被消费者获得。
  • 例如 消费者关注info消息(info.#),当所有routing key 以info开头的消息都会被分发到。
  • 所有这些都是以consumer为关注点的。

7、Topic的更多相关文章

  1. 《Kafka笔记》2、环境搭建、Topic管理

    目录 一.Kafka环境搭建和Topic管理 1 单机环境搭建 1.1 环境准备 1.1.1 JDK 安装 1.1.2 配置主机名和ip 1.1.3 关闭防火墙和防火墙开机自启动 1.1.4 zook ...

  2. ActiveMQ——activemq的详细说明,queue、topic的区别(精选)

    JMS中定义了两种消息模型:点对点(point to point, queue)和发布/订阅(publish/subscribe,topic).主要区别就是是否能重复消费. 点对点:Queue,不可重 ...

  3. rabbitmq direct、fanout、topic 三种Exchange java 代码比较

    Producer端 1.channel的创建 无论是才用什么样的Exchange,创建channel代码都是相同的,如下 ConnectionFactory factory = new Connect ...

  4. RabbitMQ ——与Spring集成及exchange的direct、topic方式实现和简单队列实现

    程序整体结构 Maven依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http: ...

  5. go语言nsq源码解读九 tcp和http中channel、topic的增删

    通过前面多篇文章,nsqlookupd基本已经解读完毕了,不过在关于channel和topic的增删上还比较模糊,所以本篇将站在宏观的角度来总结一下,tcp.go和http.go两个文件中关于chan ...

  6. 5、RabbitMQ - Exchange之 fanout \ 【direct 关键字发送】 \ topic

    pytho系列之 RabbitMQ - Exchange几种模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 Rab ...

  7. RabbitMQ、Memcache、Redis(队列、缓存)

    RabbitMQ 一.解释 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消 ...

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

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

  9. 柯南君:看大数据时代下的IT架构(8)消息队列之RabbitMQ--案例(topic起航)

    二.Topic(主题) (using the Java client) 上一篇文章中,我们进步改良了我们的日志系统.我们使用direct类型转发器,使得接收者有能力进行选择性的接收日志,,而非fano ...

随机推荐

  1. 设备树(device tree)学习笔记【转】

    转自:https://www.cnblogs.com/pengdonglin137/p/4495056.html 阅读目录(Content) 1.反编译设备树 2.分析工具fdtdump 3.Linu ...

  2. 浅谈JS的toString

    任何一个对象都有toString()方法(默认继承自Object,自己可以重写),此方法返回一个字符串. var sayYo = function () { alert("sayYo2!&q ...

  3. [C4W3] Convolutional Neural Networks - Object detection

    第三周 目标检测(Object detection) 目标定位(Object localization) 大家好,欢迎回来,这一周我们学习的主要内容是对象检测,它是计算机视觉领域中一个新兴的应用方向, ...

  4. jmeter录制移动端脚本

    jmeter录制脚本有两种方式,一种借助外部工具badbody,一种是本身的功能,使用代理服务器,介绍下如何使用代理服务器录制脚本.我一般在测app或者移动端H5页面时才会录制,所以此文也针对移动端. ...

  5. (day51)三、ORM、路由层、版本差异、流程图

    目录 一.ORM关系建立 (一)ForeignKey(一对多) (二)ManyToManyField(多对多) (三)OneToOneField(一对一) 二.django请求生命周期流程图 三.ur ...

  6. 更换github账号后,push被旧账号阻止

    和网上多数的教程不同,我是需要直接更换账号.切换后push一直被阻止.解决后记录下办法 remote: Permission to new-name/practice.git denied to ol ...

  7. luoguP3346 [ZJOI2015]诸神眷顾的幻想乡

    题意 学习了广义后缀自动机. 广义后缀自动机与普通后缀自动机的区别在于它是对多个串建的,于是可以处理多个串. 广义后缀自动机和普通后缀自动机的区别在于两个特判,可以见这篇题解 对于这题,因为叶子数量小 ...

  8. docker Dockerfile实战

    目录 Dockerfile实战 基础pm2 Dockerfile keymetrics/pm2:8-alpine keymetrics/pm2:12-alpine pm2 node Dockerfil ...

  9. 基于Django的Rest Framework框架的认证组件

    0|1一.认证组件的作用 在一个程序中有一些功能是需要登录才能使用的,原生Django中的auth组件可以用来解决这个认证问题,drf框架中也有对应的认证组件来解决这个问题. models.py   ...

  10. Azure CosmosDB (14) 使用Postman访问CosmosDB REST API

    <Windows Azure Platform 系列文章目录> 今天研究了一下如何使用Postman访问Azure CosmosDB. CosmosDB API接口,可以参考:https: ...