官方文档:https://www.rabbitmq.com/tutorials/tutorial-two-python.html
可将 work queue 中到 task 分发给多个 worker,增加了并行处理的能力。
每个 worker 都会被分配到差不多数量的 task,这种方式为 round-robin。
将任务发送到 work queue:new_task.py
#!/usr/bin/env python
import pika
import sys
connection = pika.BlockingConnection(
pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
# 避免 RabbitMQ 挂掉后丢失消息:将 queue 声明为 durable
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, # 避免 RabbitMQ 挂掉后丢失消息:将消息持久化
))
print(" [x] Sent %r" % message)
connection.close()
#!/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(b'.')) # 1 个点代表睡眠 1 s
print(" [x] Done")
# 当 task 真正被执行完后才会进行 ack
# 即便当前到 worker 挂了也不会丢失消息
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='task_queue', on_message_callback=callback)
channel.start_consuming()
运行结果:
$ python3 worker.py
[*] Waiting for messages. To exit press CTRL+C
[x] Received b'task1.'
[x] Done
[x] Received b'task3...'
[x] Done
$ python3 worker.py
[*] Waiting for messages. To exit press CTRL+C
[x] Received b'task2..'
[x] Done
[x] Received b'task4 task5'
[x] Done
$ python3 new_task.py task1.
[x] Sent 'task1.'
$ python3 new_task.py task2..
[x] Sent 'task2..'
$ python3 new_task.py task3...
[x] Sent 'task3...'
$ python3 new_task.py task4 task5
[x] Sent 'task4 task5'