Python 操作 Rabbit MQ 路由 (六)

Python 操作 Rabbit MQ 路由 (六)

一、路由(Routing):

本章打算新增加一个功能,使它可以达到仅订阅消息的一个子集。

举个栗子,我们需要把验证的错误日志信息写入日志文件(存储到磁盘),但同时仍然把所有的日志信息输出到控制台中。

二、绑定(Bindings):

绑定(Binding)是指交换机(Exchange)和队列(Queue)的关系;

绑定的时候可以带上一个额外的routing_key参数。为了避免与basic_publish的参数混淆,我们把它叫做绑定键(Binding Key)

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

注意

  • 绑定键的意义取决于交换机的类型,上一篇使用的扇形交换机会忽略这个值

三、直连交换机(Direct Exchange):

打算扩展上一篇的功能,使其基于日志的严重程度进行消息过滤。比如把一些比较严重的错误日志写入磁盘,以免将警告或信息日志上浪费磁盘空间,仅记录比较严重的错误。

上一篇我们使用的扇形交换机,没有足够的灵活性,仅能做广播的需求;

直连交换机的路由算法很简单易懂,交换机将会对绑定键和路由键进行精准匹配,从而确定消息该分发到哪个队列

图解

img

详解:可以看到type=direct,指定交换机的类型为直连交换机,它和两个队列都进行了绑定。第一个队列(Q1)使用orange作为绑定键,第二个队列(Q2)有两个绑定键,一个是black作为绑定键,另一个是green绑定键。

简单理解:当路由键为orange的消息发布到交换机,就会被路由到队列Q1中,路由键为black或green的消息发布到交换机,就会被路由到队列Q2中,其他的所有消息都将被丢弃。

四、多个绑定:

图解

img

详解:多个队列使用相同的绑定键是合法的。这样一来,直连交换机就和扇形交换机的行为一样,会将消息广播到所有匹配的队列(Q1和Q2)。

五、发送日志:

将发送消息到一个直连的交换机,把日志级别作为路由键,这样接收日志的脚本可根据严重的级别来选择它想要处理的日志,我们假设severity的值是info、warning、error中的一个

创建直连交换机:

# 交换机名为:direct_logs  类型为:直连交换机
channel.exchange_declare(exchange='direct_logs', type='direct')

发送消息:

# 交换机名称为:direct_logs
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)

七、整理本节代码:

图解
img
1.以下是send.py代码:

#!/usr/bin/python
# -*- coding: utf-8 -*- 
import pika
import sys

severity = sys.argv[1] if len(sys.argv) > 1 else 'info'
message = ' '.join(sys.argv[2:]) or "Hello World!"

# 创建一个实例  本地访问IP地址可以为 localhost 后面5672是端口地址(>以不用指定, 因为默认就是5672)
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost', 5672))

# 声明一个管道, 在管道里发送消息
channel = connection.channel()

# 指定交换机的类型为direct: 执行交换机    交换机名称: direct_logs
channel.exchange_declare(exchange='direct_logs', exchange_type='direct')

# 投递消息
channel.basic_publish(exchange='direct_logs',
                      routing_key=severity,
                      body=message
                      )

print "[x] sent {}".format(severity, message)
# 队列关闭
connection.close()

2.以下是receive.py代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import pika
import sys

# 创建实例
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))

# 声明管道
channel = connection.channel()

# 指定交换机名为 direct_logs 交换机类型为:direct
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:
    print >> sys.stderr, "Usage: %s [info] [warning] [error]" % \
                         (sys.argv[0],)
    sys.exit(1)

for severitie in severities:
    # 绑定交换机和队列  这里注意的是绑定键, 就是根据按照指定严重级别进行记录日志
    channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key=severitie)


def callback(ch, method, properties, body):
    print '[X] Received{}'.format(body,)


# 消费消息
channel.basic_consume(queue=queue_name,  # 从指定的消息队列中接收消息
                      on_message_callback=callback,  # 如果收到消息, 就调用callback函数来处理
                      )

print('=======正在等待消息========')
channel.start_consuming()  # 开始消费消息

3.仅希望保存warning和error级别日志到磁盘中,需要打开控制台并输入:

python receive.py warning error > logs_from_rabbit.log

4.希望所有日志都输出到屏幕中,打开一个新的终端,输入:

python receive.py info warning error

5.要触发一个error级别的日志,需要输入:

python send.py error '发送一个error级别的错误'
# 可以看到步骤3的控制台, 会出现:
=======正在等待消息========
[X] Received发送一个error级别的错误

简单理解:通过绑定键的名称,来进行由哪个队列进行处理

RabbitMQ 支持延迟任务通过插件 rabbitmq_delayed_message_exchange 实现。该插件能够让你发送一个延迟消息,这个消息将会在指定的时间后才会被处理。下面是实现延迟任务的步骤: 1. 安装插件 首先需要安装插件,使用以下命令安装: ```bash rabbitmq-plugins enable rabbitmq_delayed_message_exchange ``` 2. 创建交换机 创建一个延迟交换机,可以使用下面的命令: ```bash rabbitmqadmin declare exchange name=delayed_exchange type=x-delayed-message arguments='{"x-delayed-type":"direct"}' ``` 3. 发送延迟消息 使用延迟交换机来发送消息。将消息发送到该交换机,同时设置一个 x-delay 的 header,用来指定消息的延迟时间(单位是毫秒)。 ```python import pika import time connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() # 创建延迟交换机 channel.exchange_declare(exchange='delayed_exchange', exchange_type='x-delayed-message', arguments={ 'x-delayed-type': 'direct' }) # 发送延迟消息 delay_time = 5000 # 延迟 5 秒 message_body = 'Hello, world!' channel.basic_publish( exchange='delayed_exchange', routing_key='delayed_routing_key', body=message_body, properties=pika.BasicProperties( headers={'x-delay': delay_time} ) ) print(f"Sent '{message_body}' with delay {delay_time}ms") connection.close() ``` 4. 处理延迟消息 在接收端,正常处理消息即可。当消息到达时,RabbitMQ 会将其路由到指定的队列。 ```python import pika connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() # 创建队列 channel.queue_declare(queue='delayed_queue', durable=True) # 绑定队列到延迟交换机 channel.queue_bind(queue='delayed_queue', exchange='delayed_exchange', routing_key='delayed_routing_key') # 处理消息 def callback(ch, method, properties, body): print(f"Received: {body}") ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_qos(prefetch_count=1) channel.basic_consume(queue='delayed_queue', on_message_callback=callback) print('Waiting for messages...') channel.start_consuming() ``` 这样就可以实现 RabbitMQ 的延迟任务了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值