我使用celery
和rabbitmq
来处理大约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,))
答案 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,))
希望有帮助...