In the previous tutorial we built a simple logging system. We were able to broadcast log messages to many receivers.

In this tutorial we're going to add a feature to it - we're going to make it possible to subscribe only to a subset of the messages. For example, we will be able to direct only critical error messages to the log file (to save disk space), while still being able to print all of the log messages on the console.

Bindings

In previous examples we were already creating bindings. You may recall code like:

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

A binding is a relationship between an exchange and a queue. This can be simply read as: the queue is interested in messages from this exchange.

Bindings can take an extra routing_key parameter. To avoid the confusion with abasic_publish parameter we're going to call it a binding key. This is how we could create a binding with a key:

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

The meaning of a binding key depends on the exchange type. The fanout exchanges, which we used previously, simply ignored its value.

Direct exchange

Our logging system from the previous tutorial broadcasts all messages to all consumers. We want to extend that to allow filtering messages based on their severity. For example we may want the script which is writing log messages to the disk to only receive critical errors, and not waste disk space on warning or info log messages.

We were using a fanout exchange, which doesn't give us too much flexibility - it's only capable of mindless broadcasting.

We will use a direct exchange instead. The routing algorithm behind a direct exchange is simple - a message goes to the queues whose binding key exactly matches the routing keyof the message.

To illustrate that, consider the following setup:

In this setup, we can see the direct exchange X with two queues bound to it. The first queue is bound with binding key orange, and the second has two bindings, one with binding key blackand the other one with green.

In such a setup a message published to the exchange with a routing key orange will be routed to queue Q1. Messages with a routing key of black or green will go to Q2. All other messages will be discarded.

Multiple bindings

It is perfectly legal to bind multiple queues with the same binding key. In our example we could add a binding between X and Q1 with binding key black. In that case, the direct exchange will behave like fanout and will broadcast the message to all the matching queues. A message with routing key black will be delivered to both Q1 and Q2.

Emitting logs

We'll use this model for our logging system. Instead of fanout we'll send messages to a direct exchange. We will supply the log severity as a routing key. That way the receiving script will be able to select the severity it wants to receive. Let's focus on emitting logs first.

Like always we need to create an exchange first:

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

And we're ready to send a message:

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

To simplify things we will assume that 'severity' can be one of 'info', 'warning', 'error'.

Subscribing

Receiving messages will work just like in the previous tutorial, with one exception - we're going to create a new binding for each severity we're interested in.

 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)

Putting it all together

The code for emit_log_direct.py:

 #!/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:

 #!/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()

rabbitmq使用(四)的更多相关文章

  1. RabbitMQ(四) -- Routing

    RabbitMQ(四) -- Routing `rabbitmq`可以通过路由选择订阅者来发布消息. Bindings 通过下面的函数绑定Exchange与消息队列: channel.queue_bi ...

  2. 快速掌握RabbitMQ(二)——四种Exchange介绍及代码演示

    在上一篇的最后,编写了一个C#驱动RabbitMQ的简单栗子,了解了C#驱动RabbitMQ的基本用法.本章介绍RabbitMQ的四种Exchange及各种Exchange的使用场景. 1 direc ...

  3. RabbitMQ第四篇:Spring集成RabbitMQ

    前面几篇讲解了如何使用rabbitMq,这一篇主要讲解spring集成rabbitmq. 首先引入配置文件org.springframework.amqp,如下 <dependency> ...

  4. RabbitMQ的四种ExChange

    在message到达Exchange后,Exchange会根据route规则进入对应的Queue中,message可能进入一个Queue也可能进入对应多个Queue,至于进入哪个Queue或者是说哪个 ...

  5. RabbitMQ(四)

    RabbitMQ 配置 一.RabbitMQ 配置修改方式 1.修改环境变量 2.修改配置文件(只介绍这个) 3.修改运行时参数和政策 locate rabbitmq vi /var/log/rabb ...

  6. rabbitMQ第四篇:远程调用

    前言:前面我们讲解的都是本地服务器,现在如果需要远程计算机上运行一个函数,等待结果.这就是一个不同的故事了,这种模式通常被称为远程过程调用或者RPC. 本章教程我们使用RabbitMQ搭建一个RPC系 ...

  7. RabbitMQ (四) 路由选择 (Routing) -摘自网络

    本篇博客我们准备给日志系统添加新的特性,让日志接收者能够订阅部分消息.例如,我们可以仅仅将致命的错误写入日志文件,然而仍然在控制面板上打印出所有的其他类型的日志消息. 1.绑定(Bindings) 在 ...

  8. RabbitMQ (四) 路由选择 (Routing)

    上一篇博客我们建立了一个简单的日志系统,我们能够广播日志消息给所有你的接收者,如果你不了解,请查看:RabbitMQ (三) 发布/订阅.本篇博客我们准备给日志系统添加新的特性,让日志接收者能够订阅部 ...

  9. RabbitMQ笔记四:Binding,Queue,Message概念

    Binding详解   黄线部分就是binding Exchange与Exchange,Queue之间的虚拟连接,Binding中可以包含Routing key或者参数   创建binding 注意: ...

  10. rabbitmq系列四 之路由

    1.路由 在上一个的教程中,我们构建了一个简单的日志记录系统.我们能够向许多接收者广播日志消息. 在本次教程中,我们向该系统添加一些特性,比如,我只需要严重错误(erroe级别)的部分日志打印到磁盘文 ...

随机推荐

  1. 说说流控制(RTS/CTS/DTR/DSR 你都明白了吗?)【转】

    转自:http://bbs.ednchina.com/BLOG_ARTICLE_129041.HTM 以前写的博文,转过来 ============== 先引用一篇网文,作者不详,因几个地方都说自己是 ...

  2. xpath路径前可用方法测试

    $x("string-length(//h3[@class='t'])") 8 $x("string(//h3[@class='t'])") "XPa ...

  3. jdk8系列一、jdk8 Lamda表达式语法、接口的默认方法和静态方法、supplier用法

    一.简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性. 在本文中我们将学习这些新特性,并用实际 ...

  4. es6 属性及常用新属性汇总

    一.includes的作用: includes:判断isNotShowProIdArray数组里是否包含this.item.productid元素 ,若包含true !!: !!(a)的作用是将a强制 ...

  5. CGAffineTransform 缩放 / 旋转 / 平移

    CGAffineTransform此类是一个3*3矩阵的变换. - (void)transformImageView { CGAffineTransform t = CGAffineTransform ...

  6. pytest十:用例 a 失败,跳过测试用例 b 和 c 并标记失败 xfail

    当用例 a 失败的时候,如果用例 b 和用例 c 都是依赖于第一个用例的结果,那可以直接跳过用例 b 和 c 的测试,直接给他标记失败 xfail用到的场景,登录是第一个用例,登录之后的操作 b 是第 ...

  7. 步步为营-69-Razor基础

    作用:进一步将HTML代码和C#代码进行解耦 1.1 引用程序集(RazorEngine.dll,System.Web.Razor.dll) 1.1.1 可以从http://razorengine.c ...

  8. 对字符串进行频繁拼接的话,使用StringBuffer或者StringBuilder

    package zhengze; /*如果需要对字符串进行频繁拼接的话,使用StringBuffer或者StringBuilder StringBuffer:[字符串缓冲器]是线程安全的,效率低 St ...

  9. 《剑指offer》-左旋转字符串

    汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S="abc ...

  10. VS2013 生成时复制文件或目录到指定目录

    需求: 在vs2010生成成功时将项目Lib目录下Reader文件夹内的所有文件和文件夹复制到输出目录(Debug或Release目录) 方法: 打开VS2010,右键项目属性-生成事件-后期生成事件 ...