python操作rabbitmq,实现生产消费者模型
更多详情参考官方文档:https://www.rabbitmq.com/tutorials/tutorial-six-python.html
参考博客:https://blog.csdn.net/weixin_41896508/article/details/80997828
下载第三方模块pika,版本差异语法差别需指定版本
pip3 install -i https://pypi.douban.com/simple pika==0.13.1
(1)简单的生产者和消费者(无确认无持久化)
生产者producer.py代码
1 import pika 2 # 创建凭证,使用rabbitmq用户密码登录 3 credentials = pika.PlainCredentials("yang","123456") 4 # 新建连接到服务器ip 5 connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.160.135',credentials=credentials)) 6 # 创建频道 7 channel = connection.channel() 8 # 声明一个队列,用于接收消息,队列名字叫“消息队列1” 9 channel.queue_declare(queue='消息队列1') 10 11 12 # 注意在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),初学可以使用空字符串交换(exchange=''),它允许我们精确的指定发送给哪个队列(routing_key=''),参数body值发送的数据 13 channel.basic_publish(exchange='', 14 routing_key='消息队列1', 15 body='没有确认和持久化的消息队列生产者1') 16 print("消息队列1已经发送了消息") 17 # 程序退出前,确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接 18 connection.close()
执行生产者代码
pyhton3 /opt/rabbitmqtest/producer.py
访问web管理界面,登录,查看队列信息
http://192.168.160.135:15672/
消息队列1 idle 1 0 1 0.00/s
消费者consumer.py代码
1 import pika 2 # 建立与rabbitmq的连接 3 credentials = pika.PlainCredentials("yang","123456") 4 connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.160.135',credentials=credentials)) 5 channel = connection.channel() 6 channel.queue_declare(queue="消息队列1") 7 8 9 #定义一个处理消息的回调函数 10 def callbak(ch,method,properties,body): 11 print("消费者接收到了数据:%r"%body.decode("utf8")) 12 # 有消息来临,立即执行callbak,没有消息则夯住,等待消息 13 channel.basic_consume(callbak,queue="消息队列1",no_ack=True)#no_ack设置是否给消息队列确认处理正常 14 # 开始消费,接收消息 15 channel.start_consuming()
执行消费者代码
pyhton3 /opt/rabbitmqtest/consumer.py
刷新管理界面,消息队列为空是不在显示此消息队列信息
(2)确认机制的生产者和消费者(无持久化)
生产者producer_ack.py
1 import pika 2 # 创建凭证,使用rabbitmq用户密码登录 3 credentials = pika.PlainCredentials("yang","123456") 4 # 新建连接到服务器ip 5 connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.160.135',credentials=credentials)) 6 # 创建频道 7 channel = connection.channel() 8 # 声明一个队列,用于接收消息,队列名字叫“消息队列2_ack” 9 channel.queue_declare(queue='消息队列2_ack') 10 11 12 # 注意在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),初学可以使用空字符串交换(exchange=''),它允许我们精确的指定发送给哪个队列(routing_key=''),参数body值发送的数据 13 channel.basic_publish(exchange='', 14 routing_key='消息队列2_ack', 15 body='没有持久化的确认机制生产者') 16 print("消息队列2_ack已经发送了消息") 17 # 程序退出前,确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接 18 connection.close()
消费者consumer_ack.py
1 import pika 2 # 建立与rabbitmq的连接 3 credentials = pika.PlainCredentials("yang","123456") 4 connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.160.135',credentials=credentials)) 5 channel = connection.channel() 6 channel.queue_declare(queue="消息队列2_ack") 7 8 9 #定义一个处理消息的回调函数 10 def callbak(ch,method,properties,body): 11 print("消费者接收到了数据:%r"%body.decode("utf8")) 12 13 #在处理完成之后,确认消息发送之前模拟异常错误 14 #int('asd') 15 16 #确认机制的回复信息 17 ch.basic_ack(delivery_tag=method.delivery_tag) 18 # 有消息来临,立即执行callbak,没有消息则夯住,等待消息 19 channel.basic_consume(callbak,queue="消息队列2_ack",no_ack=False)#消息队列确认机制,需在回调函数进行确认 20 # 开始消费,接收消息 21 channel.start_consuming()
回调函数如果在处理之后确认之前发生异常抛错,则消息队列信息不删除,但实际已经处理,所以存在问题,实际认为没有正常处理
(3)持久化确认机制的生产者和消费者
持久化目的:在消息队列运行过程中,防止意外停止服务引起队列消息额丢失,从而进行持久化,重启后仍能看到
生产者producer_ack_durable.py
1 import pika 2 # 创建凭证,使用rabbitmq用户密码登录 3 credentials = pika.PlainCredentials("yang","123456") 4 # 新建连接到服务器ip 5 connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.160.135',credentials=credentials)) 6 # 创建频道 7 channel = connection.channel() 8 # 声明一个队列,用于接收消息,队列名字叫“消息队列_ack_durable” 9 channel.queue_declare(queue='消息队列_ack_durable',durable=True)# durable确保队列持久化 10 11 12 # 注意在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),初学可以使用空字符串交换(exchange=''),它允许我们精确的指定发送给哪个队列(routing_key=''),参数body值发送的数据 13 channel.basic_publish(exchange='', 14 routing_key='消息队列_ack_durable', 15 body='持久化确认机制生产者', 16 # 支持数据持久化:代表消息是持久的 2 17 properties=pika.BasicProperties(delivery_mode=2,) 18 ) 19 print("消息队列_ack_durable已经发送了消息") 20 # 程序退出前,确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接 21 connection.close()
消费者consumer_ack_durable.py
1 import pika 2 # 建立与rabbitmq的连接 3 credentials = pika.PlainCredentials("yang","123456") 4 connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.160.135',credentials=credentials)) 5 channel = connection.channel() 6 channel.queue_declare(queue="消息队列3_ack_durable",durable=True)# durable确保队列持久化 7 8 9 #定义一个处理消息的回调函数 10 def callbak(ch,method,properties,body): 11 print("消息队列3_ack_durable消费者接收到了数据:%r"%body.decode("utf8")) 12 13 #在处理完成之后,确认消息发送之前模拟异常错误 14 #int('asd') 15 16 #确认机制的回复信息,告诉服务端已经取走数据 17 ch.basic_ack(delivery_tag=method.delivery_tag) 18 # 有消息来临,立即执行callbak,没有消息则夯住,等待消息 19 channel.basic_consume(callbak,queue="消息队列3_ack_durable",no_ack=False)#消息队列确认机制,需在回调函数进行确认 20 # 开始消费,接收消息 21 channel.start_consuming()