RabbitMQ工作队列之Python实现

上一篇中我们介绍了经典的案例Hello,world。本篇将介绍工作队列。

消息也可以理解为任务,消息发送者可以理解为任务分配者,消息接收者可以理解为工作者,当工作者接收到一个任务,还没完成的时候,任务分配者又发一个任务过来,那就忙不过来了,于是就需要多个工作者来共同处理这些任务,这些工作者,就称为工作队列。结构图如下:

                                                                            

准备工作

在之前的例子中我们发送了一条消息“Hello World”,现在我们发送字符串来模拟复杂的任务,我们通过time.sleep()函数实现,小数点的个数代表任务复杂度.

修改send.py 代码,并重新命名new_task.py:

import sys
message = ' '.join(sys.argv[1:]) or "Hello World!"
channel.basic_publish(exchange='',
                      routing_key='hello',
                      body=message)
print " [x] Sent %r" % (message,)

修改receive.py代码,并重新命名work.py:

import time

def callback(ch, method, properties, body):
    print " [x] Received %r" % (body,)
    time.sleep( body.count('.') )
    print " [x] Done"<span class="s"></span>


循环调度

打开一个终端运行new_task.py

$ python new_task.py First message.
$ python new_task.py Second message..
$ python new_task.py Third message...
$ python new_task.py Fourth message....
$ python new_task.py Fifth message.....

打开两个终端运行work.py:

$ python worker.py
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received 'First message.'
 [x] Received 'Third message...'
 [x] Received 'Fifth message.....'

$ python worker.py
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received 'Second message..'
 [x] Received 'Fourth message....'

消息确认

消息确认就是当工作者完成任务后,会反馈给rabbitmq。修改worker.py中的回调函数:

def callback(ch, method, properties, body):
    print " [x] Received %r" % (body,)
    time.sleep( body.count('.') )
    print " [x] Done"
    ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_consume(callback,queue='hello')

消息持久化

虽然有了消息反馈机制,但是如果rabbitmq自身挂掉的话,那么任务还是会丢失。所以需要将任务持久化存储起来。声明持久化存储:

channel.queue_declare(queue='task_queue', durable=True)
在发送任务的时候,用delivery_mode=2来标记任务为持久化存储:

channel.basic_publish(exchange='',
                      routing_key="task_queue",
                      body=message,
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # make message persistent
                      ))

公平调度

虽然每个工作者是依次分配到任务,但是每个任务不一定一样。可能有的任务比较重,执行时间比较久;有的任务比较轻,执行时间比较短。如果能公平调度就最好了,使用basic_qos设置prefetch_count=1,使得rabbitmq不会在同一时间给工作者分配多个任务,即只有工作者完成任务之后,才会再次接收到任务。

                                                

channel.basic_qos(prefetch_count=1)


  
  

  
  

完整代码:

new_task.py

import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)

message = ' '.join(sys.argv[1:]) or "Hello World!"
channel.basic_publish(exchange='',
                      routing_key='task_queue',
                      body=message,
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # make message persistent
                      ))
print " [x] Sent %r" % (message,)
connection.close()

work.py

#!/usr/bin/env python
import pika
import time

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)
print ' [*] Waiting for messages. To exit press CTRL+C'

def callback(ch, method, properties, body):
    print " [x] Received %r" % (body,)
    time.sleep( body.count('.') )
    print " [x] Done"
    ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_qos(prefetch_count=1)
channel.basic_consume(callback,
                      queue='task_queue')

channel.start_consuming()




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ 延迟队列可以通过以下几个步骤来实现: 1. 安装 RabbitMQ 插件:rabbitmq_delayed_message_exchange 在 RabbitMQ 中,延迟队列可以通过使用插件 rabbitmq_delayed_message_exchange 来实现。首先需要安装该插件,可以通过以下命令进行安装: ``` rabbitmq-plugins enable rabbitmq_delayed_message_exchange ``` 2. 创建延迟交换机 创建一个用于延迟消息的交换机,类型为 x-delayed-message,可以通过以下命令进行创建: ``` rabbitmqadmin declare exchange name=<exchange_name> type=x-delayed-message arguments='{"x-delayed-type": "direct"}' ``` 其中,<exchange_name> 为交换机名称。 3. 创建队列 创建一个普通的队列,用于存储消息,可以通过以下命令进行创建: ``` rabbitmqadmin declare queue name=<queue_name> ``` 其中,<queue_name> 为队列名称。 4. 绑定队列和交换机 将队列绑定到延迟交换机上,可以通过以下命令进行绑定: ``` rabbitmqadmin declare binding source=<exchange_name> destination=<queue_name> routing_key=<routing_key> ``` 其中,<routing_key> 为路由键。 5. 发送延迟消息 发送一条延迟消息,可以通过以下代码进行实现: ```python import pika import time connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # 设置延迟时间,单位为毫秒 delay_time = 5000 # 设置消息体 message = 'Hello, RabbitMQ!' # 设置消息属性,用于指定延迟时间 properties = pika.BasicProperties( headers={ 'x-delay': delay_time } ) # 发送消息 channel.basic_publish( exchange='<exchange_name>', routing_key='<routing_key>', body=message, properties=properties ) print(f'[x] Sent "{message}" with {delay_time}ms delay') connection.close() ``` 其中,需要设置消息属性 headers,用于指定延迟时间。 6. 接收延迟消息 接收延迟消息,可以通过以下代码进行实现: ```python import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # 定义回调函数 def callback(ch, method, properties, body): print(f'[x] Received "{body.decode()}"') # 接收消息 channel.basic_consume( queue='<queue_name>', on_message_callback=callback, auto_ack=True ) print('[*] Waiting for messages. To exit press CTRL+C') channel.start_consuming() connection.close() ``` 在接收消息时,可以通过回调函数获取消息体。 以上就是实现 RabbitMQ 延迟队列的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值