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

时间:2014-12-21 10:39:22

标签: django architecture rabbitmq celery multiserver

我设法让DjangoRabbitMQ以及Celery在单机上工作。我已按照here的说明进行操作。现在我想让它们一起工作,但是当它们在不同的服务器上时。我不希望DjangoCeleryCelery了解Django

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

现在,我已经在Django多次调用,例如

create_project.apply_async(args, countdown=10)

我想用类似的调用直接替换为RabbitMQ(正如我所说Django不应该依赖Celery)。然后,RabbitMQ应该通知Celery(如果可能的话)并且Celery将完成其工作(可能与Django但通过REST接口进行交互。)< / p>

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

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

修改

  

我认为对于我的用例芹菜是总开销。简单的RabbitMQ   使用自定义客户端进行路由将完成工作。我已经尝试过简单了   用例(一个服务器),它完美地工作。它应该很容易   使通信多服务器准备就绪。我不喜欢芹菜。它是   &#34;魔法&#34;,隐藏太多细节,配置起来并不容易。但我会留下这个问题,因为我对别人的意见感兴趣。

1 个答案:

答案 0 :(得分:5)

缺少

  

我怎样才能做到这一点?

Celery只发送任务名称和一系列参数作为消息正文。那就是你的场景绝对符合Celery的运作方式。

  

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

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

@task
def foo():
    pass

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

@task
def foo():
    pass

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

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

更简单的替代方案

上述存根任务的替代方法是发送任务by name

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

关于消息模式

  

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

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

权衡

  

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

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

  • 如果您使用Celery,您可能会失去RabbitMQ API的一些灵活性,但您可以轻松开发,同时获得开发速度和更低的部署复杂性 - 它基本上只是起作用。

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

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

任何足够先进的技术都无法与魔法区分开来; - )

  

我不喜欢芹菜。它是&#34;魔法&#34;,隐藏了太多细节,并不容易配置。

我会选择不同意。它可能是&#34;魔法&#34;在Arthur C. Clarke's意义上,但如果将它与普通的RabbitMQ设置进行比较,它肯定很容易配置。当然,如果你也是那个做RabbitMQ设置的人,它可能只是添加一层你从未获得任何东西的抽象层。也许你的开发人员会这样做?