Celery:使用 PostgreSQL 而不是 RabbitMQ

Posted

技术标签:

【中文标题】Celery:使用 PostgreSQL 而不是 RabbitMQ【英文标题】:Celery: Use PostgreSQL instead of RabbitMQ 【发布时间】:2018-05-08 11:41:21 【问题描述】:

是否可以在 celery 中使用不同的消息代理?

例如:我想使用 PostgreSQL 而不是 RabbitMQ。

AFAIK 仅在结果后端支持:http://docs.celeryproject.org/en/latest/userguide/configuration.html#database-backend-settings

从 PostgreSQL 9.5 开始,SKIP LOCKED 可以实现强大的消息/工作队列。见https://blog.2ndquadrant.com/what-is-select-skip-locked-for-in-postgresql-9-5/

【问题讨论】:

你读过 Celery 关于经纪人的文档吗? docs.celeryproject.org/en/latest/userguide/… 数据库传输支持代码之前被删除,但最近被添加回来:github.com/celery/kombu/tree/master/kombu/transport/sqlalchemy @RonanBoiteau 根据文档,有几种支持的传输模式。 amqp://、redis://、sqs:// 和 qpid://。好像不支持使用 PostgreSQL。 【参考方案1】:

是的,您可以使用 postgres 作为代理而不是 rabbitmq。这是一个简单的例子来演示它。

from celery import Celery 


broker = 'sqla+postgresql://user:pass@host/dbname'

app = Celery(broker=broker)

@app.task
def add(x, y):
    return x + y

排队任务

In [1]: from demo import add

In [2]: add.delay(1,2)
Out[2]: <AsyncResult: 4853190f-d355-48ae-8aba-6169d38fad39>

工人结果:

[2017-12-02 08:11:08,483: INFO/MainProcess] Received task: t.add[809060c0-dc7e-4a38-9e4e-9fdb44dd6a31]  
[2017-12-02 08:11:08,496: INFO/ForkPoolWorker-1] Task t.add[809060c0-dc7e-4a38-9e4e-9fdb44dd6a31] succeeded in 0.0015781960000822437s: 3

在最新(celery==4.1.0,kombu==4.1.0,SQLAlchemy==1.1.1)版本上测试。

【讨论】:

使用 postgre 比 rabbitMQ 有优势吗? @pelos 是的。减少堆栈中另一个组件的维护/部署开销。但是,如果您有高工作负载,建议不要使用 db 作为代理。相关讨论github.com/celery/celery/issues/5149。 这不再起作用了。在最近的 Celery 版本中,您不能将数据库用作代理。 @RamyM.Mousa 您使用的是哪个版本? celery==5.0.0 似乎也可以正常工作。【参考方案2】:

是否可以在 celery 中使用不同的消息代理?

在版本 4 之前,肯定是的!我曾经在 Celery 3 中使用 mongodb 作为消息代理,遵循official document。

所以如果想用PostgreSQL作为broker,没关系,Celery也支持SQLAlchemy.

但是,如果你想在 Celery 4.0 中使用它,可能会有点困难,我认为一种方法是更改​​ Kombu 的代码,是的,它是 Kombu,而不是 Celery!

【讨论】:

以上是关于Celery:使用 PostgreSQL 而不是 RabbitMQ的主要内容,如果未能解决你的问题,请参考以下文章

查看 celery 任务是不是存在

为啥 Postgresql 使用过滤器而不是索引?

postgresql pg 库采用 windows 用户名而不是 postgresql

[Django] celery的替代品 funboost

我们啥时候可以在 PostgreSQL 中使用标识符号而不是其名称?

PostgreSQL是否使用tablename_id而不是id来命名主键?