python使用rabbitMQ介绍二(工作队列模式)
一模式介绍
第一章节的生产-消费者模式,是非常简单的模式,一发一收。在实际的应用中,消费者有的时候需要工作较长的时间,则需要增加消费者。
队列模型:
这时mq实现了一下几个功能:
- rabbitmq循环调度,将消息循环发送给不同的消费者
- 消息确认机制。为了确保一个消息不会丢失,RabbitMQ支持消息的确认 , 一个 ack(acknowlegement) 是从消费者端发送一个确认去告诉RabbitMQ 消息已经接收了、处理了,RabbitMQ可以释放并删除掉了。如果一个消费者死掉了(channel关闭、connection关闭、或者TCP连接断开了)而没有发送ack,RabbitMQ 就会认为这个消息没有被消费者处理,并会重新发送到生产者的队列里,如果同时有另外一个消费者在线,rabbitmq将会将消息很快转发到另外一个消费者中。 那样的话你就能确保虽然一个消费者死掉,但消息不会丢失。 这个是没有超时的,当消费方(consumer)死掉后RabbitMQ会重新转发消息,即使处理这个消息需要很长很长时间也没有问题。消息的 acknowlegments 默认是打开的,在前面的例子中关闭了: no_ack = True . 现在删除这个标识 然后 发送一个 acknowledgment。
- 消息持久化,将消息写入硬盘中。
- 公平调度。在一个消费者未处理完一个消息之前不要分发新的消息给它,而是将这个新消息分发给另一个不是很忙的消费者进行处理。为了解决这个问题我们可以在消费者代码中使用 channel.basic.qos ( prefetch_count = 1 ),将消费者设置为公平调度。
二 代码示例
生产者:

1 #!/usr/bin/env python 2 import pika 3 import sys 4 5 parameters = pika.ConnectionParameters(host='localhost') 6 connection = pika.BlockingConnection(parameters) 7 8 channel = connection.channel() 9 channel.queue_declare(queue='task_queue', durable=True) 10 11 for i in range(10): 12 message = 'Hello World: {}'.format(i) 13 channel.basic_publish(exchange='', 14 routing_key='task_queue', 15 body=message, 16 properties=pika.BasicProperties(delivery_mode=2)) 17 print(" [x] Sent %r " % message) 18 19 connection.close()
消费者:

#!/usr/bin/env python import pika import time parameters = pika.ConnectionParameters(host='localhost') connection = pika.BlockingConnection(parameters) channel = connection.channel() channel.queue_declare(queue='task_queue', durable=True) print(' [*] Warting for messages. To exit press CTRL+C') def call_back(ch, method, properties, body): print(" [x] Received %r" % body) time.sleep(body.count(b'.')) print(" [x] Done") ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_qos(prefetch_count=1) channel.basic_consume(call_back, queue='task_queue') channel.start_consuming()
生产者打印输出:
1 Task: 2 [x] Sent 'Hello World: 0' 3 [x] Sent 'Hello World: 1' 4 [x] Sent 'Hello World: 2' 5 [x] Sent 'Hello World: 3' 6 [x] Sent 'Hello World: 4' 7 [x] Sent 'Hello World: 5' 8 [x] Sent 'Hello World: 6' 9 [x] Sent 'Hello World: 7' 10 [x] Sent 'Hello World: 8' 11 [x] Sent 'Hello World: 9'
woerk1输出:
[*] Warting for messages. To exit press CTRL+C [x] Received b'Hello World: 0' [x] Done [x] Received b'Hello World: 2' [x] Done [x] Received b'Hello World: 4' [x] Done [x] Received b'Hello World: 6' [x] Done [x] Received b'Hello World: 7' [x] Done [x] Received b'Hello World: 9' [x] Done
worker二输出:
[*] Warting for messages. To exit press CTRL+C [x] Received b'Hello World: 1' [x] Done [x] Received b'Hello World: 3' [x] Done [x] Received b'Hello World: 5' [x] Done [x] Received b'Hello World: 8' [x] Done
三 队列信息
在web管理页面,可以看到channel情况
在queue页面,可以看到
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?