使用 Django 和 Elastic beantalk 实现并行任务的最佳方法是啥?

Posted

技术标签:

【中文标题】使用 Django 和 Elastic beantalk 实现并行任务的最佳方法是啥?【英文标题】:What's the best way to implement parallel tasks with Django and Elastic beanstalk?使用 Django 和 Elastic beantalk 实现并行任务的最佳方法是什么? 【发布时间】:2013-04-15 20:31:21 【问题描述】:

我一直在尝试用 django 实现 celery,用 SQS 实现弹性 beantalk,但我仍然不知道应该如何在后台启动工作人员,看来我需要在 EB 之外创建一个 AMI。我什至走的是正确的道路吗?有没有更好的方法来处理并行任务?

【问题讨论】:

【参考方案1】:

更新: 我为此找到了一个更简单、更稳定的替代解决方案。在这个问题中查看我的答案:How do you run a worker with AWS Elastic Beanstalk?

我只需要为我正在进行的项目弄清楚这一点。这需要一些修补,但最终解决方案很容易实施。您可以使用 ebextension 挂钩中的 files: 指令将三个文件“动态”添加到服务器。这三个文件是:

    启动守护进程的脚本(位于 /etc/init.d/) 一个配置文件,配置守护进程启动脚本,位于/etc/default/ 一个将环境变量从您的应用程序复制到 celeryd 环境并启动服务的 shell 脚本(部署后)

启动脚本可以是存储库中的默认脚本,因此它直接来自 github。

您的项目必须采用该配置。您需要将自己的应用名称添加到CELERY_APP 设置中,并且可以通过CELERYD_OPTS 设置将其他参数传递给worker(例如,可以在此处设置并发值)。

然后,您还需要将项目的环境变量传递给工作守护程序,因为它需要与主应用程序相同的环境变量。一个例子是 celery 工作人员需要能够连接到 SQS 和可能的 S3 的 AWS 密钥。您可以通过简单地将当前应用程序中的环境变量附加到配置文件中来做到这一点:

cat /opt/python/current/env | tee -a /etc/default/celeryd

最后应该启动 celery worker。此步骤需要在代码库部署到服务器后进行,因此需要在“发布”部署后激活。您可以通过使用未记录的部署后挂钩来做到这一点。 /opt/elasticbeanstalk/hooks/appdeploy/post/ 中的任何 shell 文件都将由 elasticbeanstalk 部署后执行。因此,您可以将service celeryd restart 命令添加到该文件夹​​中的脚本文件中。为方便起见,我将环境变量的复制和启动命令放在了一个文件中。

请注意,您不能直接使用services: 指令来启动守护进程,因为这将尝试在代码库部署到服务器之前启动 celeryd 工作程序,因此无法正常工作(因此“post”部署脚本)。

好的,所有这些放在一起,唯一需要做的就是在您的代码库的主目录中创建一个文件./ebextensions/celery.config,其中包含以下内容(当然被您的代码库采用):

files:
  "/etc/init.d/celeryd":
    mode: "000755"
    owner: root
    group: root
    source: https://raw2.github.com/celery/celery/22ae169f570f77ae70eab03346f3d25236a62cf5/extra/generic-init.d/celeryd

  "/etc/default/celeryd":
    mode: "000755"
    owner: root
    group: root
    content: |
      CELERYD_NODES="worker1"
      CELERY_BIN="/opt/python/run/venv/bin/celery"
      CELERY_APP="yourappname"
      CELERYD_CHDIR="/opt/python/current/app"
      CELERYD_OPTS="--time-limit=30000"
      CELERYD_LOG_FILE="/var/log/celery/%N.log"
      CELERYD_PID_FILE="/var/run/celery/%N.pid"
      CELERYD_USER="ec2-user"
      CELERYD_GROUP="ec2-user"
      CELERY_CREATE_DIRS=1

  "/opt/elasticbeanstalk/hooks/appdeploy/post/myapp_restart_celeryd.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      # Copy env vars to celeryd and restart service
      su -c "cat /opt/python/current/env | tee -a /etc/default/celeryd" $EB_CONFIG_APP_USER
      su -c "service celeryd restart" $EB_CONFIG_APP_USER

services: 
  sysvinit:
    celeryd:
      enabled: true
      ensureRunning: false

希望这会有所帮助。

【讨论】:

以上是关于使用 Django 和 Elastic beantalk 实现并行任务的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Elastic Beanstalk 上的 Docker + Django

Elastic Beanstalk 上 Django/Celery 的权限问题

Django Channels 2.4 和 Websockets 在 Elastic Beanstalk 和 ElastiCache 上给出 502 错误

使用 Elastic Beanstalk 部署 Vue JS Django 应用程序

如何使用 django-elasticsearch-dsl 将 django-modeltranslation 创建的列索引为 Elastic?

AWS Elastic Beanstalk 上禁止使用 Django 403