前面已经介绍过怎么安装rabbitmq以及要使用的三方库
因此这里直接进入实例
1、发布端代码
# new_task.py
import pika # 导入pika
import sys # 导入系统模块
# 开启链接,链接本地的rabbitmq
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
# 建立一个链接
channel = connection.channel()
# 指定一个队列,名为task_queue durable=true表示 为了不让队列消失,需要把队列声明为持久化(durable)
# 这样做的目的是:确保在RabbitMq重启之后queue_declare队列不会丢失
channel.queue_declare(queue='task_queue', durable=True)
# 获取运行脚本时的输入
message = ' '.join(sys.argv[1:]) or "Hello World!"
channel.basic_publish(exchange='',# exchange参数就是交换机的名称。空字符串代表默认或者匿名交换机:消息将会根据指定的routing_key分发到指定的队列。
routing_key='task_queue', # 指明队列
body=message, # 发送的消息
properties=pika.BasicProperties(
delivery_mode = 2, # 另外,我们需要把我们的消息也要设为持久化——将delivery_mode的属性设为2
))
print (" [x] Sent %r" % message)
# 关闭链接
connection.close()
2、消费段代码
# new_worker.py
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.decode().count('.') )
print(" [x] Done")
# 配置消息确认
# 一个很容易犯的错误就是忘了basic_ack,后果很严重。消息在你的程序退出之后就会重新发送,
# 如果它不能够释放没响应的消息,RabbitMQ就会占用越来越多的内存。
ch.basic_ack(delivery_tag = method.delivery_tag)
# 使用公平调度,这样是告诉RabbitMQ,再同一时刻,不要发送超过1条消息给一个工作者(worker),
# 直到它已经处理了上一条消息并且作出了响应。这样,RabbitMQ就会把消息分发给下一个空闲的工作者(worker)。
channel.basic_qos(prefetch_count=1)
# 这里我们已经将no_ack=True删掉了,表示开启消息确认,但是必须要在消息执行完后进行确认,看 ch.basic_ack配置即可
# 意义:防止某个工作者执行一半意外终止后消息丢失和它掌管的消息都丢失,配置后就是在执行完毕后会告诉发布者然后执行下一个
channel.basic_consume(callback,queue='task_queue')
channel.start_consuming()
3、如何运行
消费端:
python new_worker.py
注意:这里尽量多运行即可消费端,便于观察运行原理
发布端:
python new_task.py hello.
python new_task.py hello..
python new_task.py hello...
python new_task.py hello....
python new_task.py hello.....
运行多次,查看消费端的输出