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. awk常用命令

    1.统计TCP的连接数量,其中LISTEN多少个,ESTABLISHED多少个. [root@heiniao ~]# netstat -ant Active Internet connections ...

  2. LeetCode98. 验证二叉搜索树

     验证二叉搜索树  *  * https://leetcode-cn.com/problems/validate-binary-search-tree/description/  *  * algor ...

  3. 【oracle】查看表空间信息

    -- 数据库查询表空间使用情况SELECT Upper(F.TABLESPACE_NAME) "表空间名", D.TOT_GROOTTE_MB/1024 "表空间大小(G ...

  4. CentOS单机安装FastDFS&整合Nginx

    单机安装 一 准备工作 准备linux服务器或虚拟机,这里是虚拟机,操作系统CentOS 6.4 Tracker 和 Storage 安装在一台机器上 FastDFS 5.08版本 1,准备软件 软件 ...

  5. 突然看到原来除了jar包还有war包啊?????

    先来说说区别: 首先,jar包呢,是一个压缩文件,可以由很多文件压缩而成,,简单来说就是,jar包是别人写好的一些类,然后对这些类 进行打包,这就是jar包,你可以直接用这些  jar包,使用里面的类 ...

  6. cocos2dx 3.17(Windows下) 接入skynet和sprotol

    大致流程一致,但是他的github上的版本,没有Windows的版本.打开他的win的工程会提示缺少一个模块. 本人环境 cocos2dx 3.17.1 当前最新 skynet-无视-当前最新 VS2 ...

  7. Pencil 基于Electron的GUI原型工具之菜单再探

    为什么要重试呢? 主要是觉得Pencil这个工具还是比较有价值.就像Linus对Linux下分发版的态度"让用户有选择"一样,在现在这个Sass服务.Web服务化越来越普遍越便利的 ...

  8. 用Java开发的【智能语音开发板MEGA ESP32AI】

    有点激动 ~ ~ ~ 新鲜出炉,用视频看看效果哦 我们新研发出世的语音开发板MEGA ESP32AI,来看看吧,有点腻害哦!!!先演示下功能语音控制开关等.播报天气 戳下面链接看视频哦? MEGA E ...

  9. touch.js - 移动设备上的手势识别与事件库

    Touch.js 是移动设备上的手势识别与事件库, 由百度云Clouda团队维护,也是在百度内部广泛使用的开发工具.Touch.js手势库专为移动设备设计.Touch.js对于网页设计师来说,是一款不 ...

  10. 我的周记12——"站在现在看前人对未来的预测,很有意思"

    万里风云三尺剑,一庭花草半床书 聊聊最近很火的5G B站有个up主  老师好我叫何同学  优秀啊,点赞. 他做了一个5G测速的视频火啦 视频链接:https://www.bilibili.com/vi ...