1

我设法获得Django并在单台机器RabbitMQCelery工作。我已按照此处的说明进行操作。现在我想让它们一起工作,但在它们位于不同服务器上的情况下。我不想Django知道Celery也不Celery知道Django

所以,基本上我只想Django将一些消息发送到RabbitMQ队列(可能是 id、任务类型、可能是其他一些信息),然后我想RabbitMQ将该消息(如果可能的话)发布到Celery另一台服务器上。Celery/Django不应该互相了解,基本上我想要很容易替换其中任何一个的架构。

现在我有Django几个电话,比如

create_project.apply_async(args, countdown=10)

我想用直接对 RabbitMQ 的类似调用来替换它(正如我所说的Django不应该依赖于Celery)。然后,RabbitMQ应该通知Celery(如果可能)Celery并将完成其工作(可能与Django但通过REST接口交互)。

此外,我需要Celery在两台或多台服务器上拥有工作人员,并且我只想RabbitMQ根据消息中的某些字段通知其中一个。如果这太复杂了,我可以检查每个任务(在不同的机器上),比如:这是你应该做的事情吗(比如检查消息中的 ip 地址字段),如果它不仅仅是停止执行任务。

我怎样才能做到这一点?如果可能的话,我更喜欢代码+配置示例,而不仅仅是理论解释。

编辑:

我认为对于我的用例芹菜是总开销。带有自定义客户端的简单 RabbitMQ 路由将完成这项工作。我已经尝试过简单的用例(一台服务器)并且效果很好。使通信多服务器准备好应该很容易。我不喜欢芹菜。它很“神奇”,隐藏了太多细节,而且不容易配置。但我会留下这个问题,因为我对别人的意见感兴趣。

4

1 回答 1

6

它的短处

我怎样才能做到这一点?

Celery 只发送任务名称和一组序列化的参数作为消息体。那就是你的场景完全符合 Celery 的运作方式。

如果可能的话,我更喜欢代码+配置示例,而不仅仅是理论解释。

对于客户端应用程序,即您的 Django 应用程序,定义存根任务,如下所示:

@task
def foo():
    pass

对于 Celery 处理,在您的远程服务器上,定义要执行的实际任务。

@task
def foo():
    pass

重要的是任务在双方都存在于同一个 Python 包中(即app.tasks.py,否则 Celery 将无法将消息与实际任务相匹配。

请注意,这也意味着如果您设置了 Django 应用程序,您的 Django 应用程序将变得不可测试CELERY_ALWAYS_EAGER=True,除非您使 Celery 应用程序在tasks.py本地对 Django 应用程序可用。

更简单的选择

上述存根任务的替代方法是按名称发送任务:

>>> app.send_task('tasks.add', args=[2, 2], kwargs={})
<AsyncResult: 373550e8-b9a0-4666-bc61-ace01fa4f91d>

关于消息模式

此外,我需要在两台或多台服务器上安装 Celery 工作人员,并且我希望 RabbitMQ 根据消息中的某些字段仅通知其中一个。

RabbitMQ 提供了几种消息传递模式,它们的教程写得非常好并且切中要害。你想要的(一个工人处理的一条消息)可以通过简单的队列/交换设置轻松实现,如果你不做任何其他事情,它(至少使用 Celery)是默认设置。如果您需要特定的工作人员来处理特定的任务/响应特定的消息,请使用 Celery 的任务路由,它与 RabbitMQ 的队列和交换概念密切相关。

权衡取舍

我认为对于我的用例芹菜是总开销。带有自定义客户端的简单 RabbitMQ 路由将完成这项工作。我已经尝试过简单的用例(一台服务器)并且效果很好。

当然,您可以开箱即用地使用 RabbitMQ,但代价是必须处理 RabbitMQ 提供的较低级别的 API。Celery 添加了一个任务抽象,使得构建任何生产者/消费者场景变得非常简单,基本上只使用普通的 Python 函数或方法。请注意,这不是对 RabbitMQ 或 Celery 的更好/更差判断——与工程决策一样,需要权衡取舍:

  • 如果您使用 Celery,您可能会失去一些 RabbitMQ API 的灵活性,但您会获得开发的便利性,同时获得开发速度和较低的部署复杂性——它基本上可以正常工作。

  • 如果您直接使用 RabbitMQ,您将获得灵活性,但随之而来的是您需要自行管理的部署复杂性。

根据您项目的要求,任何一种方法都可能是有效的——您的电话,真的。

任何足够先进的技术都与魔法没有区别;-)

我不喜欢芹菜。它很“神奇”,隐藏了太多细节,而且不容易配置。

我会选择不同意。在Arthur C. Clarke 的意义上,它可能是“神奇的” ,但如果将它与普通的 RabbitMQ 设置进行比较,它肯定很容易配置。当然,如果您也是进行 RabbitMQ 设置的人,它可能只是添加了一个抽象层,而您并没有真正从中获得任何好处。也许您的开发人员会?

于 2014-12-24T00:51:36.913 回答