如何在芹菜任务中实现异步rabbitmq客户端鼠兔或pyrabbit?

时间:2017-11-02 10:41:10

标签: python asynchronous rabbitmq celery pika

我使用celeryrabbitmq来处理大约1000万个任务。任务的输出是一个存储在远程rabbitmq中的json。我正在使用Pika将消息发布到远程rabbitmq中的不同队列。目前我收到此错误pika.exceptions.ConnectionClosed: Connection,因为pika不是异步的。我找到了另一个异步客户端pyrabbit。但是我无法在我的代码中实现它。我是否需要为每项任务创建新连接?这是我的代码:

from __future__ import absolute_import
from test_celery.celery import app
import pika

credentials = pika.PlainCredentials('user', 'pass')
parameters = pika.ConnectionParameters('myip',5672,'/',credentials)
connection = pika.BlockingConnection(parameters)
channel = connection.channel()

@app.task(bind=True,default_retry_delay=10,time_limit=22)
def get_data(self,url):
    ..# Processing code
    message = json.dumps(data)
    channel.basic_publish(exchange='',routing_key=country,          
                    body=message,
                    properties=pika.BasicProperties(delivery_mode = 2,))

2 个答案:

答案 0 :(得分:0)

我没有经过测试的答案,但对于您的问题“我是否需要为每项任务创建新连接?”这通常是性能不好的,通常的解决方案是连接池。我做了一个快速搜索,遇到https://github.com/bninja/pika-pool这可能会有所帮助。

答案 1 :(得分:0)

我认为您的问题是您的连接已被设置为模块的全局变量。我发现它在使用时最终会关闭。

我的工作是创建一个由任务调用的独立“发布者”模块。这可确保连接保持新鲜。

那就是说,听起来你正在搅拌很多数据。您应该能够使用connection.is_open来检查连接是否已打开,如果它处于打开状态,则返回True。如果它没有打开...然后重新连接。

所以,也许这会奏效:

def connect():
    credentials = pika.PlainCredentials('user', 'pass')
    parameters = pika.ConnectionParameters('myip',5672,'/',credentials)
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()
    return connection, channel

connection, channel = connect()

@app.task(bind=True,default_retry_delay=10,time_limit=22)
def get_data(self,url):
    ..# Processing code
    message = json.dumps(data)

    if connection.is_open == False:
        connection, channel = connect()

    channel.basic_publish(exchange='',routing_key=country,          
                    body=message,
                    properties=pika.BasicProperties(delivery_mode = 2,))

希望有帮助...