【问题标题】:Usage of RabbitMQ queues with Django在 Django 中使用 RabbitMQ 队列
【发布时间】:2020-03-31 08:07:45
【问题描述】:

我正在尝试向我的 Django 应用程序添加一些实时功能,因为我在我的 django 项目中使用 RabbitMQ 和 Celery,所以我想做的是:我有一个外部 Python 脚本将数据发送到 RabbitMQ > 从 RabbitMQ 它应该从 Django 应用程序中检索。

我正在发送一些布偶数据,如下所示:

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.queue_declare(queue='Test')

channel.basic_publish(exchange='',
                      routing_key='Test',
                      body='Hello world!')

print(" [x] Sent 'Hello World!'")

connection.close()

我想做的是:一旦我发送Hello World!,我的 Django 应用程序应该会收到该字符串,以便我可以使用它执行一些操作,例如将其保存在我的数据库中,将其传递给HTML 模板或简单地将其打印到我的控制台。

我的实际问题是我仍然不知道该怎么做。我将 Celery 添加到我的 Django 项目中,但我不知道如何连接到 RabbitMQ 并接收消息。我必须用 Django 频道来做吗?有这方面的教程吗?我找到了各种关于在 Django 中使用 RabbitMQ 和 Celery 的材料,但没有关于这个特定问题。

【问题讨论】:

    标签: python django rabbitmq


    【解决方案1】:

    这与 Celery 没有直接关系。

    你可以这样解决:

    1. 在 Django 中创建一个管理命令,对传入的消息/数据执行任何需要执行的操作 (https://docs.djangoproject.com/en/3.0/howto/custom-management-commands/)
    2. 创建一个消费者,它也可以是一个 Django 命令,然后在单独的进程中启动,它不是常规 Django 进程的一部分(尽管它可以是 Django 代码的一部分)。在这个消费者中,您侦听队列,每当数据进入时,都会调用 (1.) 中的管理命令。

    当然,1. 和 2. 也可以在一个命令中完成。我把它分开来更好地说明不同的方面。而且您可能有不同的任务并重用一个消费者。此外,如果您已经 (1.) 您可以像这样重用它,并且您可以轻松地对其进行测试,而无需消费者的开销。

    更多关于 RabbitMQ python 消费者:https://github.com/celery/celery/blob/master/celery/worker/consumer/consumer.py

    这里是 Celery 消费者: https://github.com/celery/celery/blob/master/celery/worker/consumer/consumer.py 因为芹菜当然有它自己的消费者。虽然它看起来相当通用,但简单的消费者应该不那么复杂。

    (我只写过 NSQ python 消费者作为 Django 的一部分,因此没有直接体验过 RabbitMQ 消费者(仅作为 Celery 的后端)。)


    编辑:您应该问自己的是 - 首先,我是否希望将实时数据保存并存储在我的 Django 应用程序中?

    如果是 - 那么 RabbitMQ+Consumer 是一种非常有效的方法。

    如果不是,如果这只是为了用户 - 您也可以考虑通过 API 直接将其公开给您的前端(并使用 ajax 调用来获取它)。

    如果不是,但您想缓冲数据以避免碰到生成数据的其他应用程序 - 那么队列是一个非常好的工具。不过,在这种情况下,您可能会更改消费者而不是保存数据,而是将其公开给您的前端。如果您只需要支持新的浏览器,您可以使用 Django 3 现在支持的 websocket:

    https://blog.heroku.com/in_deep_with_django_channels_the_future_of_real_time_apps_in_django

    【讨论】:

    • 嘿,谢谢你回答我的问题!好的,你说得更清楚了,但我有一些问题:使用这种方法,如果我的 Django 应用程序和消费者部分是两个不同的进程,我将如何将数据传递到前端?你认为使用 Django-Channels 是完成我的任务的更好方法吗?
    • 您只能在保存(到数据库)后将其传递给前端,然后再由常规 Django 视图(或您支持前端的任何内容)再次检索。我还没有使用过 Django-Channels。我正在添加有关该方法的编辑。
    • 好的!清除!我看到了你的编辑,不,我不需要将它存储在我的 Django 数据库中,它已经存储在其他地方;我需要的是在生成后尽快将其展示给用户。我确实考虑过创建一个 API,但让我担心的是我会用请求敲击端点:每个用户每秒将有 2 个请求(或更多)——我担心它会在我的系统上产生性能问题
    • 其实我当时的想法是想办法把数据发送到RabbitMQ,然后想办法把它从队列中直接带到前端
    猜你喜欢
    • 2013-07-25
    • 2021-07-29
    • 1970-01-01
    • 2015-11-20
    • 2021-06-14
    • 2011-07-22
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    相关资源
    最近更新 更多