上篇文章中,我们构建了一个简单的日志系统。接下来,我们将丰富它:能够使用不同的severity来监听不同等级的log。比如我们希望只有error的log才保存到磁盘上。

1. Bindings绑定

上篇文章中我们是这么做的绑定:

  1. channel.queue_bind(exchange=exchange_name,
  2. queue=queue_name)
channel.queue_bind(exchange=exchange_name,
queue=queue_name)

绑定其实就是关联了exchange和queue。或者这么说:queue对exchagne的内容感兴趣,exchange要把它的Message deliver到queue中。

实际上,绑定可以带routing_key 这个参数。其实这个参数的名称和basic_publish 的参数名是相同了。为了避免混淆,我们把它成为binding key。
    使用一个key来创建binding :

  1. channel.queue_bind(exchange=exchange_name,
  2. queue=queue_name,
  3. routing_key='black')
channel.queue_bind(exchange=exchange_name,
queue=queue_name,
routing_key='black')

对于fanout的exchange来说,这个参数是被忽略的。

2. Direct exchange

Direct exchange的路由算法非常简单:通过binding key的完全匹配,可以通过下图来说明。


    exchange X和两个queue绑定在一起。Q1的binding key是orange。Q2的binding key是black和green。
    当P publish key是orange时,exchange会把它放到Q1。如果是black或者green那么就会到Q2。其余的Message都会被丢弃。

3. Multiple bindings

      多个queue绑定同一个key是可以的。对于下图的例子,Q1和Q2都绑定了black。也就是说,对于routing key是black的Message,会被deliver到Q1和Q2。其余的Message都会被丢弃。

4. Emitting logs

首先是我们要创建一个direct的exchange:

  1. channel.exchange_declare(exchange='direct_logs',
  2. type='direct')
channel.exchange_declare(exchange='direct_logs',
type='direct')

我们将使用log的severity作为routing key,这样Consumer可以针对不同severity的log进行不同的处理。
publish:

  1. channel.basic_publish(exchange='direct_logs',
  2. routing_key=severity,
  3. body=message)
channel.basic_publish(exchange='direct_logs',
routing_key=severity,
body=message)

我们使用三种severity:'info', 'warning', 'error'.

5. Subscribing

对于queue,我们需要绑定severity:

  1. result = channel.queue_declare(exclusive=True)
  2. queue_name = result.method.queue
  3. for severity in severities:
  4. channel.queue_bind(exchange='direct_logs',
  5. queue=queue_name,
  6. routing_key=severity)
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue for severity in severities:
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key=severity)

6. 最终版本

The code for emit_log_direct.py:

  1. #!/usr/bin/env python
  2. import pika
  3. import sys
  4. connection = pika.BlockingConnection(pika.ConnectionParameters(
  5. host='localhost'))
  6. channel = connection.channel()
  7. channel.exchange_declare(exchange='direct_logs',
  8. type='direct')
  9. severity = sys.argv[1] if len(sys.argv) > 1 else 'info'
  10. message = ' '.join(sys.argv[2:]) or 'Hello World!'
  11. channel.basic_publish(exchange='direct_logs',
  12. routing_key=severity,
  13. body=message)
  14. print " [x] Sent %r:%r" % (severity, message)
  15. connection.close()
#!/usr/bin/env python
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='direct_logs',
type='direct') severity = sys.argv[1] if len(sys.argv) > 1 else 'info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='direct_logs',
routing_key=severity,
body=message)
print " [x] Sent %r:%r" % (severity, message)
connection.close()

The code for receive_logs_direct.py:

  1. #!/usr/bin/env python
  2. import pika
  3. import sys
  4. connection = pika.BlockingConnection(pika.ConnectionParameters(
  5. host='localhost'))
  6. channel = connection.channel()
  7. channel.exchange_declare(exchange='direct_logs',
  8. type='direct')
  9. result = channel.queue_declare(exclusive=True)
  10. queue_name = result.method.queue
  11. severities = sys.argv[1:]
  12. if not severities:
  13. print >> sys.stderr, "Usage: %s [info] [warning] [error]" % \
  14. (sys.argv[0],)
  15. sys.exit(1)
  16. for severity in severities:
  17. channel.queue_bind(exchange='direct_logs',
  18. queue=queue_name,
  19. routing_key=severity)
  20. print ' [*] Waiting for logs. To exit press CTRL+C'
  21. def callback(ch, method, properties, body):
  22. print " [x] %r:%r" % (method.routing_key, body,)
  23. channel.basic_consume(callback,
  24. queue=queue_name,
  25. no_ack=True)
  26. channel.start_consuming()
#!/usr/bin/env python
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='direct_logs',
type='direct') result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue severities = sys.argv[1:]
if not severities:
print >> sys.stderr, "Usage: %s [info] [warning] [error]" % \
(sys.argv[0],)
sys.exit(1) for severity in severities:
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key=severity) print ' [*] Waiting for logs. To exit press CTRL+C' def callback(ch, method, properties, body):
print " [x] %r:%r" % (method.routing_key, body,) channel.basic_consume(callback,
queue=queue_name,
no_ack=True) channel.start_consuming()

我们想把warning和error的log记录到一个文件中:

  1. $ python receive_logs_direct.py warning error > logs_from_rabbit.log
$ python receive_logs_direct.py warning error > logs_from_rabbit.log

打印所有log到屏幕:

  1. $ python receive_logs_direct.py info warning error
  2. [*] Waiting for logs. To exit press CTRL+C
$ python receive_logs_direct.py info warning error
[*] Waiting for logs. To exit press CTRL+C

转载自: anzhsoft: http://blog.csdn.net/anzhsoft/article/details/19630147

参考资料:

1. http://www.rabbitmq.com/tutorials/tutorial-four-python.html

RabbitMQ Routing 消息路由的更多相关文章

  1. RabbitMQ --- Routing(路由)

    目录 RabbitMQ --- Hello Mr.Tua RabbitMQ --- Work Queues(工作队列) RabbitMQ --- Publish/Subscribe(发布/订阅) 前言 ...

  2. 关于rabbitmq的消息路由的同步问题

    http://www.cnblogs.com/me-sa/archive/2012/11/12/rabbitmq_ram_or_disk_node.html我是看了上面的博客明白了一些原理的,我之前一 ...

  3. RabbitMQ消息队列(五):Routing 消息路由

        上篇文章中,我们构建了一个简单的日志系统.接下来,我们将丰富它:能够使用不同的severity来监听不同等级的log.比如我们希望只有error的log才保存到磁盘上. 1. Bindings ...

  4. RabbitMQ消息队列(五):Routing 消息路由 2[原]

    上一篇文章使用的是Direct的Exchange,但是没有指定Queue的名字,这样只能是先运行Consumer之后,Producer在运行发消息Consumer才能收到,否则先运行Producer发 ...

  5. RabbitMQ消息队列(五):Routing 消息路由[转]

    上篇文章中,我们构建了一个简单的日志系统.接下来,我们将丰富它:能够使用不同的severity(严重程度)来监听不同等级的log.比如我们希望只有error的log才保存到磁盘上. 1. Bindin ...

  6. (转)RabbitMQ消息队列(五):Routing 消息路由

    上篇文章中,我们构建了一个简单的日志系统.接下来,我们将丰富它:能够使用不同的severity来监听不同等级的log.比如我们希望只有error的log才保存到磁盘上. 1. Bindings绑定 上 ...

  7. .Net RabbitMQ之消息通信 构建RPC服务器

    1.消息投递服务 RabbitMQ是一种消息投递服务,怎么理解这句话呢?即RabbitMQ即不是消息的生产者,也是消息的消费者.他就像现实生活中快递模式,消费者在电商网站上下单买了一件商品,此时对应的 ...

  8. RabbitMQ(4) 未路由的消息、TTL和死信

    未路由的消息 当生产这发送的消息到达指定的交换器后,如果交换器无法根据自身类型.绑定的队列以及消息的路由键找到匹配的队列,默认情况下消息将被丢弃.可以通过两种方式 处理这种情况,一是在发送是设置man ...

  9. rabbitmq高级消息队列

    rabbitmq使用 什么是消息队列 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串,也可以很复杂,可以包含嵌入对象. 消息队列是一种应用间的通信方式,消息发送后 ...

随机推荐

  1. Debian 9 Stretch国内常用镜像源

     随着Debian 9的普及,但由于伟大的墙的存在,那就有必要整理一下国内的镜像站点. 1.使用说明 一般情况下,修改/etc/apt/sources.list文件,将Debian的默认源地址改成新的 ...

  2. vcpkg custom triplet

    需求是要弄一个用 pip 发布的python 包,使用 boost-python 桥接 原C++代码,发布时不想带 boost-python 的运行时库,因此需要弄静态的 boost-python库, ...

  3. Spring整合quartz关闭,关闭Tomcat Servlet容器时内存泄漏

    出错信息 22-Sep-2017 06:19:51.064 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearR ...

  4. MVC Request生命周期(综合总结)

    当用户在浏览器输入一个URL地址后,浏览器会发送一个请求到服务器.这时候在服务器上第一个负责处理请求的是IIS.然后IIS再根据请求的URL扩展名将请求分发给不同的处理程序处理. 流程如下: 当请求一 ...

  5. MySQL8.0安装

    背景 MySQl 8.0 出来已经有段时间了,据说性能有很大提高,在网上看过很多安装教程,大同小异, 在这里亲身实战实战下MySQL8.0在Windows10系统下的安装,以下为详细的安装步骤. 1. ...

  6. hbase-连接流程

    root和meta表 在版本0.9.8之前,存在root表,之后的版本中去除了root表,meta表主要记录了每个表在region的分布情况. meta结构 从表格中可以看出,rowkey格式:tab ...

  7. CentOS 7 minimal网络配置

    centos最小化安装没有ifconfig命令,可以使用  ip addr  查看网络信息,习惯ifconfig的用户,则使用 yum -y install net-tools 即可 ; 如果yum不 ...

  8. 设计模式学习心得<享元模式 Flyweight>

    享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝 ...

  9. 数据流图——从软考真题中学画数据流图DFD

    文章目录 题目 画顶层图 画0层图 解题技巧 题目 建议将题目复制到word后与此文分屏查看.后面需要多次查看题目. 某高校欲开发一个成绩管理系统,记录并管理所有选修课程的学生的平时成绩和考试成绩, ...

  10. p2p技术之n2n源码核心简单分析一

    首先在开篇之前介绍下内网打洞原理 场景:一个服务器S1在公网上有一个IP,两个私网机器C1,C2 C1,C2分别由NAT1和NAT2连接到公网,我们需要借助S1将C1,C2建立直接的TCP连接,即由C ...