Django + RabbitMQ + Celery 都在不同的机器(服务器)上



我设法DjangoRabbitMQCelery在单台机器上工作。我已经按照这里的指示进行操作。现在我想让它们一起工作,但当它们在不同的服务器上时。我不想DjangoCelery一无所知,也不想Celery Django.

所以,基本上我只想Django向队列发送一些消息RabbitMQ(可能是 id、任务类型,也许是其他一些信息(,然后我希望RabbitMQ发布该消息(如果可能(到另一台服务器上CeleryCelery/Django不应该互相了解,基本上我想要的建筑很容易取代其中任何一个。

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

create_project.apply_async(args, countdown=10)

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

此外,我需要在两台或多台服务器上Celery工作人员,我希望RabbitMQ根据消息中的某个字段只通知其中一个。如果这很复杂,我可以签入每个任务(在不同的机器上(,例如:这是您应该做的事情(例如检查消息中的 IP 地址字段(,如果它不仅仅是停止执行任务。

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

编辑:

我认为对于我的用例来说,芹菜是总开销。简单兔子MQ 使用自定义客户端进行路由将完成这项工作。我已经尝试过简单 用例(一台服务器(,它运行良好。应该很容易 使通信多服务器准备就绪。我不喜欢芹菜。是的 "神奇",隐藏了太多细节,不容易配置。但我会让这个问题保持活力,因为我对其他人的意见感兴趣。

它的短线

我怎样才能做到这一点?

Celery 仅将任务名称和一组序列化的参数作为消息正文发送。也就是说,您的场景绝对符合芹菜的运作方式。

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

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

@task
def foo():
    pass

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

@task
def foo():
    pass

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

请注意,这也意味着如果你设置了 Django 应用程序CELERY_ALWAYS_EAGER=True,否则你的 Django 应用程序变得不可测试,除非你让 Celery 应用程序的tasks.py在本地提供给 Django 应用程序。

更简单的替代方案

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

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

关于消息模式

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

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

权衡取

我认为对于我的用例来说,芹菜是总开销。使用自定义客户端的简单 RabbitMQ 路由将完成这项工作。我已经尝试了简单的用例(一台服务器(,它运行良好。

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

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

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

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

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

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

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

相关内容

最新更新