python中通过pika,应用RabbitMQ,有多种形式:
一、简单队列模型
简单队列模型:交换机此处不工作(exchange=‘’),只针对唯一指定的队列进行操作的生产者、消费者模型,
使用queue实现:基于内存中的一个queue对象
#!/usr/bin/env python # -*- coding:utf-8 -*- import Queue import threading message = Queue.Queue(10) def producer(i): while True: message.put(i) def consumer(i): while True: msg = message.get() for i in range(12): t = threading.Thread(target=producer, args=(i,)) t.start() for i in range(10): t = threading.Thread(target=consumer, args=(i,)) t.start()
使用RabbitMQ实现:基于另一台服务器的RabbitMQ Server
(一)实现流程
此处,无论是生产者还是消费者:
首先,都需要与RabbitMQ Server建立socket连接,并获得操作句柄,
然后,通过操作句柄查找或者创建指定队列,
有了指定队列,才能开始添加或读取信息的操作:
生产者:向队列中添加数据、之后关闭连接,
消费者:开始等待队列中的数据信息,从队列中读取数据、数据通过参数传入回调函数、回调函数自执行,数据是否立即删除由参数no_ack指定,
#!/usr/bin/env python # -*- coding:utf-8 -*- # 简单队列模型:交换机不工作,只针对唯一指定的队列进行操作, # -----------------------生产者-------------------------------- # 0、导入RabbitMQ在Python中的接口pika, import pika # 1、封装socket逻辑部分,由host指定访问的RabbitMQ Server, connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) # 2、获得操作句柄,通过此句柄对RabbitMQ进行操作, channel = connection.channel() # 3、检查队列是否已存在,不存在时创建并命名,消费者取数据时需通过名字找到相应队列, channel.queue_declare(queue='hello',durable=True) # 4、向队列中添加数据,注意三个参数, channel.basic_publish(exchange='', # 交换机,此处不工作, routing_key='hello', # 队列名称, body='Hello World!', # 添加的数据, properties=pika.BasicProperties(delivery_mode=2), # make message properties数据持久性 ) # 操作提示信息,非必需 print(" [x] Sent 'Hello World!'") # 5、添加数据完毕,关闭socket连接 connection.close()
#!/usr/bin/env python # -*- coding:utf-8 -*- # 简单队列模型:交换机不工作,只针对唯一指定的队列进行操作, # ---------------------消费者--------------------- # 0、导入RabbitMQ在Python中的接口pika, import pika # 1、封装socket逻辑部分,由host指定访问的RabbitMQ Server, connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) # 2、获得操作句柄,通过此句柄对RabbitMQ进行操作, channel = connection.channel() # 3、检查队列是否已存在,不存在时创建并命名,避免消费者先于生产者启动时报错, channel.queue_declare(queue='hello') # 5、从指定队列中取数据,以参数body方式传入回调函数,并自执行回调函数, # def callback(ch, method, properties, body): # print(" [x] Received %r" % body) # # channel.basic_consume(callback, # queue='hello', # no_ack=True) # no_ack:True表示队列中的数据取过就直接删除,无论执行结果如何,效率高, # no_ack:False表示队列中数据取过后不直接删除,执行成功后才删除,安全性高, def callback(ch, method, properties, body): print(" [x] Received %r" % body) ch.basic_ack(delivery_tag=method.delivery_tag) # no_ack=False时,需要在回调函数中添加这句代码 channel.basic_qos(prefetch_count=1) # 数据谁来谁取,不按奇偶数顺序 channel.basic_consume(callback, queue='hello', no_ack=False) print(' [*] Waiting for messages. To exit press CTRL+C') # 4、开始等待队列中的数据到来, channel.start_consuming()
(二)重点参数
1、数据不丢失(消费者no_ack)
no_ack=True:队列中的数据取过后直接删除,无论回调函数的执行结果如何,效率高,
no_ack=False:队列中数据取过后不直接删除,回调函数执行成功后才删除,安全性高,
注意:当no_ack=False时,需要在回调函数中添加一句代码:ch.basic_ack(delivery_tag=method.delivery_tag)

2、数据不丢失(生产者durable)
durable=True:将数据写入硬盘,支持数据的持久性,同时需要设置properties.delivery_mode=2,
durable=Flase:为默认值,将数值保留在内存,若出现掉线或异常,数据可能丢失,

3、消息获取顺序(消费者)
默认是多个消费者按照自然顺序排队获取消息,通过如下设置,可以控制谁来谁取,避免个别消费者太慢影响进程,

#!/usr/bin/env python # -*- coding:utf-8 -*- # 简单队列模型:交换机不工作,只针对唯一指定的队列进行操作, # -----------------------生产者-------------------------------- import pika connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() # 声明队列 channel.queue_declare(queue='hello',durable=True) # 向队列中添加数据 channel.basic_publish(exchange='', # 交换机,此处不工作, routing_key='hello', # 队列名称, body='Hello World!', # 添加的数据, properties=pika.BasicProperties(delivery_mode=2), # make message properties数据持久性 ) print(" [x] Sent 'Hello World!'") connection.close() # ---------------------消费者--------------------- import pika connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() # 声明队列 channel.queue_declare(queue='hello') # 从队列中取数据并执行回调函数 def callback(ch, method, properties, body): print(" [x] Received %r" % body) ch.basic_ack(delivery_tag=method.delivery_tag) # no_ack=False时,需要在回调函数中添加这句代码 channel.basic_qos(prefetch_count=1) # 数据谁来谁取,不按奇偶数顺序 channel.basic_consume(callback, queue='hello', no_ack=False,) print(' [*] Waiting for messages. To exit press CTRL+C') channel.start_consuming()
浙公网安备 33010602011771号