路由
(使用Pika Python客户端)
先决条件
本教程假定RabbitMQ 已在标准端口(5672)的本地主机上安装并运行。如果您使用其他主机,端口或凭据,则连接设置需要进行调整。
在哪里获得帮助
如果您在阅读本教程时遇到困难,可以 通过邮件列表与我们联系。
先决条件
与其他Python教程一样,我们将使用Pika RabbitMQ客户端 版本1.0.0。
本教程的重点
在上一教程中,我们构建了一个简单的日志记录系统。我们能够向许多接收者广播日志消息。
在本教程中,我们将向其中添加功能-我们将使仅订阅消息的子集成为可能。例如,我们将只能将严重错误消息定向到日志文件(以节省磁盘空间),同时仍然能够在控制台上打印所有日志消息。
绑定
在前面的示例中,我们已经在创建绑定。您可能会想起类似的代码:
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')
绑定密钥的含义取决于交换类型。我们之前使用的 扇出交换只是忽略了它的价值。
直接交换
上一教程中的日志系统将所有消息广播给所有使用者。我们想要扩展它以允许根据邮件的严重性过滤邮件。例如,我们可能希望将日志消息写入磁盘的脚本仅接收严重错误,而不会在警告或信息日志消息上浪费磁盘空间。
我们使用的是扇出交换,它并没有给我们带来太大的灵活性-它只能进行无意识的广播。
我们将使用直接交换。直接交换背后的路由算法很简单-消息进入其绑定密钥与消息的路由密钥完全匹配的队列 。
为了说明这一点,请考虑以下设置:
在此设置中,我们可以看到绑定了两个队列的直接交换X。第一个队列绑定键为橙色,第二个绑定键为两个,一个绑定键为black,另一个绑定键为green。
在这种设置中,使用路由键橙色发布到交换机的消息 将被路由到队列Q1。路由键为黑色 或绿色的消息将转到Q2。所有其他消息将被丢弃。
多重绑定
用相同的绑定密钥绑定多个队列是完全合法的。在我们的示例中,我们可以使用绑定键black在X和Q1之间添加绑定。在这种情况下,直接交换的行为将类似于扇出,并将消息广播到所有匹配的队列。带有黑色路由键的消息将同时传递给 Q1和Q2。
发射日志
我们将在记录系统中使用此模型。我们将发送消息到直接交换机,而不是扇出。我们将提供日志严重性作为路由键。这样,接收脚本将能够选择其想要接收的严重性。让我们首先关注发射日志。
像往常一样,我们需要首先创建一个交换:
channel.exchange_declare(exchange='direct_logs',
exchange_type='direct')
我们已经准备好发送一条消息:
channel.basic_publish(exchange='direct_logs',
routing_key=severity,
body=message)
为简化起见,我们将假定“严重性”可以是“信息”,“警告”,“错误”之一。
订阅
接收消息的工作方式与上一教程一样,但有一个例外-我们将为感兴趣的每种严重性创建一个新的绑定。
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
for severity in severities:
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key=severity)
放在一起
emit_log_direct.py (source)
#!/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) > 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()
receive_logs_direct.py (source)
#!/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(queue='', 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(
queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()
如果您只想将“警告”和“错误”(而不是“信息”)日志消息保存到文件中,只需打开控制台并键入:
python receive_logs_direct.py warning error > logs_from_rabbit.log
如果您想在屏幕上查看所有日志消息,请打开一个新终端并执行以下操作:
python receive_logs_direct.py info warning error
# => [*] Waiting for logs. To exit press CTRL+C
例如,要发出错误日志消息,请键入:
python emit_log_direct.py error "Run. Run. Or it will explode."
# => [x] Sent 'error':'Run. Run. Or it will explode.'
继续学习第5篇教程,以了解如何根据模式侦听消息。
生产非适用性免责声明
请记住,本教程和其他教程都是教程。它们一次展示一个新概念,并且可能有意过分简化了某些事情,而忽略了其他事情。例如,为了简洁起见,很大程度上省略了诸如连接管理,错误处理,连接恢复,并发性和度量收集之类的主题。此类简化的代码不应视为已准备就绪。
在使用您的应用程序之前,请先阅读其余文档。我们特别推荐以下指南:发布者确认和消费者确认, 生产清单和监控。
获取帮助并提供反馈
如果您对本教程的内容或与RabbitMQ有关的任何其他主题有疑问,请随时在RabbitMQ邮件列表中询问。
帮助我们改善文档<3
如果您想对该网站做出贡献,可以在GitHub上找到其来源。只需分叉存储库并提交拉取请求。谢谢!