繁体   English   中英

如何在 python 中使用 pika (RabbitMQ) 向消费者添加多处理

[英]How to add multiprocessing to consumer with pika (RabbitMQ) in python

我在 python 中使用 pika 框架编写了非常基本的生产者-消费者代码。 问题是 - 消费者端在队列中的消息上运行太慢。 我进行了一些测试,发现我可以通过多处理将工作流程加快 27 倍。 问题是 - 我不知道向我的代码添加多处理功能的正确方法是什么。

import pika
import json
from datetime import datetime
from functions import download_xmls


def callback(ch, method, properties, body):
    print('Got something')
    body = json.loads(body)
    type = body[-1]['Type']
    print('Object type in work currently ' + type)
    cnums = [x['cadnum'] for x in body[:-1]]
    print('Got {} cnums to work with'.format(len(cnums)))

    date_start = datetime.now()
    download_xmls(type,cnums)
    date_end = datetime.now()
    ch.basic_ack(delivery_tag=method.delivery_tag)
    print('Download complete in {} seconds'.format((date_end-date_start).total_seconds()))


def consume(queue_name = 'bot-test'):
    parameters = pika.URLParameters('server@address')
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()
    channel.queue_declare(queue=queue_name, durable=True)
    channel.basic_qos(prefetch_count=1)
    channel.basic_consume(callback, queue='bot-test')
    print(' [*] Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()

如何从这里开始添加多处理功能?

Pika有大量示例代码 ,建议您查看。 请注意,此代码仅作为示例使用。 在线程上进行工作时,您将不得不使用更智能的方式来管理线程。

目的是不阻塞运行Pika的IO循环的线程,并从工作线程中正确回调回IO循环。 这就是为什么存在add_callback_threadsafe并在该代码中使用它的原因。


注意: RabbitMQ团队监视rabbitmq-users 邮件列表 ,仅在某些情况下回答关于StackOverflow的问题。

import pika
import json
from multiprocessing import Process
from datetime import datetime
from functions import download_xmls
import multiprocessing
import concurrent.futures


def do_job(body):
    body = json.loads(body)
    type = body[-1]['Type']
    print('Object type in work currently ' + type)
    cnums = [x['cadnum'] for x in body[:-1]]
    print('Got {} cnums to work with'.format(len(cnums)))

    date_start = datetime.now()
    download_xmls(type,cnums)
    date_end = datetime.now()
    ch.basic_ack(delivery_tag=method.delivery_tag)
    print('Download complete in {} seconds'.format((date_end-date_start).total_seconds()))

def callback(ch, method, properties, body):
    print('Got something')
    p = Process(target=do_job,args=(body))
    p.start()
    p.join()
    
def consume(queue_name = 'bot-test'):
    parameters = pika.URLParameters('server@address')
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()
    channel.queue_declare(queue=queue_name, durable=True)
    channel.basic_qos(prefetch_count=1)
    channel.basic_consume(callback, queue='bot-test')
    print(' [*] Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()

def get_workers():
    try:
        return multiprocessing.cpu_count()
    except NotImplementedError:
        return 4

workers = get_workers()

with concurrent.futures.ProcessPoolExecutor() as executor:
    for i in range(workers):
        executor.submit(consume)

以上只是简单的演示,如何在此处包含多处理执行。 我建议您通过文档 go 进一步优化代码并达到您的要求。

https://docs.python.org/3/library/multiprocessing.html#the-process-class

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM