一、Routing(路由) (using the Java client)

在前面的学习中,构建了一个简单的日志记录系统,能够广播所有的日志给多个接收者,在该部分学习中,将添加一个新的特点,就是可以只订阅一个特定的消息源,也就是说能够直接把关键的错误日志消息发送到日志文件保存起来,不重要的日志信息文件不保存在磁盘中,但是仍然能够在控制台输出,那么这便是我们这部分要学习的消息的路由分发机制。

二、Bindings(绑定)

在前面的学习中已经创建了绑定(bindings),代码如下:
  channel.queueBind(queueName, EXCHANGE_NAME, "");    

一个绑定就是一个关于exchange和queue的关系,它可以简单的被理解为:队列是从这个exchange中获取消息的。

绑定可以采取一个额外的routingKey的参数,为了避免与basicPublish参数冲突,称之为一个绑定Key,这是如何创建一个带routingKey的绑定的关键。

channel.queueBind(queueName, EXCHANGE_NAME, "black");

一个绑定Key依赖于exchange的类型,像之前使用fanout类型的exchange,完全忽略了该绑定key的值。

三、Direct exchange(直接交换机)


前面实现的日志记录系统中广播所有的消息给所有的消费者,现在对其进行扩展,允许根据信息的严重程度来对消息进行过滤,比如,希望一个程序写入到磁盘的日志消息只接收错误的消息,而不是浪费磁盘保存所有的日志消息。

为了实现这个目标,使用一个fanout类型的exchange,显然是不能够满足这样的需求的,因为它只能广播所有的消息。

为此将使用一个direct exchange来代替fanout exchange,direct exchange使用简单的路由算法,将消息通过绑定的Key匹配将要到达的队列。

从上面的结构图中可以看出direct exchange X绑定着两个queue(Q1,Q2),第一个queue绑定的routingKey为orange,第二个有两个routingKey被绑定,一个routingKey为black,另外一个routingKey为green.

说明:发送带有routingKey为orange的消息到X(exchange)中,X将该消息路由到Q1中,发送带有routingKey为black和green的消息都将被路由到Q2中,其他所有消息将会被丢弃。

四、Multiple bindings(多绑定)

多个队列绑定相同的routingKey是允许的,在上述实例中,可以把X和Q1用routingKey:black绑定起来,这种情况下,direct exchange将像fanout类型的exchange一样会将消息广播都到所有匹配的queues中,即一个routingKey为black的消息将会被发送到Q1和Q2中。

五、Emitting logs(发送的日志)

使用direct代替fanout类型的exchange,发送消息到一个direct exchange中,将根据消息的重要程度作为routingKey,这样接收程序能够选择它想要接收的日志信息,首先必须先创建一个exchange.

    channel.exchangeDeclare(EXCHANGE_NAME, "direct");
其次,发送一条信息:
   channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
为了简化程序,将severity设定为info、warning、error三种类型中的一种。

六、Subscribing(订阅消息)

接收者根据自己感兴趣的severity来创建一个新到的绑定。

String queueName = channel.queueDeclare().getQueue();

for(String severity : argv){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}

七、Putting it all together(代码实现)

EmitLogDirect.java代码清单如下:


  1. public class EmitLogDirect {
  2. private static final String EXCHANGE_NAME = "direct_logs";
  3. public static void main(String[] argv)
  4. throws java.io.IOException {
  5. ConnectionFactory factory = new ConnectionFactory();
  6. factory.setHost("localhost");
  7. Connection connection = factory.newConnection();
  8. Channel channel = connection.createChannel();
  9. channel.exchangeDeclare(EXCHANGE_NAME, "direct");
  10. String severity = getSeverity(argv);
  11. String message = getMessage(argv);
  12. channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
  13. System.out.println(" [x] Sent '" + severity + "':'" + message + "'");
  14. channel.close();
  15. connection.close();
  16. }
  17. //..
  18. }

ReceiveLogsDirect代码清单如下:

  1. public class ReceiveLogsDirect {
  2. private static final String EXCHANGE_NAME = "direct_logs";
  3. public static void main(String[] argv)
  4. throws java.io.IOException,
  5. java.lang.InterruptedException {
  6. ConnectionFactory factory = new ConnectionFactory();
  7. factory.setHost("localhost");
  8. Connection connection = factory.newConnection();
  9. Channel channel = connection.createChannel();
  10. channel.exchangeDeclare(EXCHANGE_NAME, "direct");
  11. String queueName = channel.queueDeclare().getQueue();
  12. if (argv.length < 1){
  13. System.err.println("Usage: ReceiveLogsDirect [info] [warning] [error]");
  14. System.exit(1);
  15. }
  16. for(String severity : argv){
  17. channel.queueBind(queueName, EXCHANGE_NAME, severity);
  18. }
  19. System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
  20. QueueingConsumer consumer = new QueueingConsumer(channel);
  21. channel.basicConsume(queueName, true, consumer);
  22. while (true) {
  23. QueueingConsumer.Delivery delivery = consumer.nextDelivery();
  24. String message = new String(delivery.getBody());
  25. String routingKey = delivery.getEnvelope().getRoutingKey();
  26. System.out.println(" [x] Received '" + routingKey + "':'" + message + "'");
  27. }
  28. }
  29. }
	编译和往常一样(参见以往教程用于编译和类路径的建议)。现在,为了方便起见,我们将使用一个环境变量$CP(%CP%在Windows上)的运行时类路径的例子。
如果你只想保存 “警告”和“错误”(而不是“信息”)日志消息到一个文件,打开一个控制台和type: [*] Waiting for logs. To exit press CTRL+C [x] Sent 'error':'Run. Run. Or it will explode.'
$ java -cp $CP ReceiveLogsDirect warning error > logs_from_rabbit.log
$ java -cp $CP ReceiveLogsDirect info warning error
$ java -cp $CP EmitLogDirect error "Run. Run. Or it will explode."

RabbitMQ学习总结(6)——消息的路由分发机制详解的更多相关文章

  1. Android事件分发机制详解

    事件分发机制详解 一.基础知识介绍 1.经常用的事件有:MotionEvent.ACTION_DOWN,MotionEvent.ACTION_MOVE,MotionEvent.ACTION_UP等 2 ...

  2. IOS 触摸事件分发机制详解

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:MelonTeam 前言 很多时候大家都不关心IOS触摸事件的分发机制的实现原理,当遇到以下几种情形的时候你很可能抓破头皮都找不到解决方案 ...

  3. Android开发——事件分发机制详解

    0. 前言   转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52566965 深入学习事件分发机制,是为了解决在Android开发中 ...

  4. Android View 事件分发机制详解

    想必很多android开发者都遇到过手势冲突的情况,我们一般都是通过内部拦截和外部拦截法解决此类问题.要想搞明白原理就必须了解View的分发机制.在此之前我们先来了解一下以下三个非常重要的方法: di ...

  5. Android事件分发机制详解(2)----分析ViewGruop的事件分发

    首先,我们需要 知道什么是ViewGroup,它和普通的View有什么区别? ViewGroup就是一组View的集合,它包含很多子View和ViewGroup,是Android 所有布局的父类或间接 ...

  6. 【Android面试查漏补缺】之事件分发机制详解

    前言 查漏补缺,查漏补缺,你不知道哪里漏了,怎么补缺呢?本文属于[Android面试查漏补缺]系列文章第一篇,持续更新中,感兴趣的朋友可以[关注+收藏]哦~ 本系列文章是对自己的前段时间面试经历的总结 ...

  7. RabbitMQ学习总结(3)——入门实例教程详解

    一.起航 本章节,柯南君将从几个层面,用官网例子讲解一下RabbitMQ的实操经典程序案例,让大家重新回到经典"Hello world!"(The simplest thing t ...

  8. android 事件分发机制详解(OnTouchListener,OnClick)

    昨天做东西做到触摸事件冲突,以前也经常碰到事件冲突,想到要研究一下Android的事件冲突机制,于是从昨天开始到今天整整一天时间都要了解这方面的知识,这才懂了安卓的触摸和点击事件的机制.探究如下: 首 ...

  9. Android事件分发机制详解(1)----探究View的事件分发

    探究View的事件分发 在Activity中,只有一个按钮,注册一个点击事件 [java] view plaincopy button.setOnClickListener(new OnClickLi ...

随机推荐

  1. 【hiho一下第十二周】刷油漆

    [题目链接]:http://hihocoder.com/problemset/problem/1055 [题意] [题解] 设f[x][i]表示以第x个节点为根的子树; 不选x这个节点,然后子树里面选 ...

  2. Centos如何安装 jdk 环境变量

    一.编辑 profile 文件 vim /etc/profile 二.在 profile 文件下面最下面加上以下内容 export JAVA_HOME=/usr/local/java/jdk1.7.0 ...

  3. hdu 2435 dinic算法模板+最小割性质

    #include<stdio.h> #include<queue> #include<string.h> using namespace std; #define ...

  4. 转-----------------------js window.open() 操作

    <% if request("infoid")<>"" then set rs=conn.execute("select * fro ...

  5. 回想四叉树LOD地形(上)

           唉.~事实上这是在差点儿相同一年前实现的东西,但当时没作好记录.放了那么久了,假设不做点总结的话,好像有点对不起自己,于是·········还是做点什么吧.        我脑洞比較小, ...

  6. 使用记事本开发第一个java程序

    记事本是开发java程序最基础的一个工具 第一步:编写 新建一个文件名为Hello的文本文档,并将文件扩展名改为.java. 在文本框内输入我们的程序代码 ——————————————我是分割线——— ...

  7. nginx报 File not found 错误

    原因可能非常多,但对于刚開始学习的人.大部分应该是/etc/nginx/conf.d/default.conf里面的php解析部分配置不正确. 解决的话就是把root定义.在server下加上,这样r ...

  8. android:layout_gravity 和android:gravit的区别?

    Android:layout_gravity 和android:gravit的区别? android:gravity是调整元素本身的内容或元素包含的子元素显示的位置,默认是显示在左侧 android: ...

  9. Linux下安装PHP7.1并做关联APACHE处理

    1.复制php压缩包到/usr/local/src 2.解压 tar -zxvf php-7.1.2.tar.gz 3.编译安装(请先安装apache和mysql) ./configure --pre ...

  10. CSS中alt和title属性的正确使用

    1.在<img>标签中的使用 alt:全称为alttext,实质是当图片无法正确显示时用于替换(在IE下同时起到了title的作用,即鼠标滑过时文字提示): title:鼠标经过时文字提示 ...