python3 RabbitMQ ( Routing !)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangxiaodong88/article/details/83211407

预备知识

What This Tutorial Focuses On

在前面的教程中,我们构建了一个简单的日志系统。我们能够向许多接收器广播日志消息。

在本教程中,我们将为它添加一个特性——我们将使订阅消息的一个子集成为可能。例如,我们将能够仅将关键错误消息直接指向日志文件(以节省磁盘空间),同时仍然能够在控制台打印所有日志消息。

绑定

在前面的例子中,我们已经创建了绑定。您可能会回忆代码如下:

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

绑定是交换器和队列之间的关系。这可以简单地理解为:队列对来自此交换器的消息感兴趣。

绑定可以使用额外的routing_key参数。为了避免与basic_publish参数混淆,我们将它称为绑定键。这就是我们如何创建一个键绑定:

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

绑定键的含义取决于交换类型。我们以前使用过的fanout交换交换机,只是忽略了它的价值。

Direct exchange

我们的日志系统从以前的教程广播所有消息到所有消费者。我们希望扩展此功能,以允许根据消息的严重程度对其进行过滤。例如,我们可能希望将日志消息写入磁盘的脚本只接收关键错误,而不是在警告或信息日志消息上浪费磁盘空间。

我们使用的是fanout交换器,这并没有给我们太多的灵活性——它只能够进行盲目的广播。

我们将使用直接交换。直接交换背后的路由算法很简单——消息转到队列,其绑定键与消息的路由键完全匹配。

为了说明这一点,考虑以下设置:
在这里插入图片描述

在这个设置中,我们可以看到直接exchange X,它绑定了两个队列。第一个队列用绑定键橙色绑定,第二个队列有两个绑定,一个用绑定键黑色绑定,另一个用绿色绑定。

在这样的设置中,发布到交换器的带有路由关键字橙色的消息将被路由到队列Q1。带有黑色或绿色路由键的消息将转到Q2。所有其他消息将被丢弃。

多个绑定

在这里插入图片描述

使用相同的绑定键绑定多个队列是完全合法的。在我们的示例中,我们可以使用绑定键black在X和Q1之间添加绑定。在这种情况下,直接交换将表现得像扇出,并将消息广播到所有匹配的队列。带有路由密钥黑色的消息将同时发送到Q1和Q2。

发送日志

我们将在日志系统中使用这个模型。我们将发送消息到一个直接交换器,而不是fanout。我们将提供日志严重性作为路由键。这样,接收脚本就能够选择它希望接收的严重性。让我们首先关注发出日志。

像往常一样,我们需要首先创建一个交换:

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

我们准备发送一个消息:

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

为了简化问题,我们假设“严重性”可以是“信息”、“警告”、“错误”。

订阅

接收消息的工作方式将与上一教程一样,只有一个例外——我们将为感兴趣的每个严重性创建一个新的绑定。

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)

将代码放在一起来看下

在这里插入图片描述
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',
                         exchange_type='direct')

severity = sys.argv[1] if len(sys.argv) > 2 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',
                         exchange_type='direct')

result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue

severities = sys.argv[1:]
if not severities:
    sys.stderr.write("Usage: %s [info] [warning] [error]\n" % 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()

猜你喜欢

转载自blog.csdn.net/yangxiaodong88/article/details/83211407
今日推荐