用于 elasticbeanstalk 上自动缩放的 django 应用程序的多个 celerybeat 实例
Multiple instances of celerybeat for autoscaled django app on elasticbeanstalk
我正在尝试找出构建 Django 应用程序的最佳方法,该应用程序使用 Celery 在自动扩展的 AWS ElasticBeanstalk 环境中处理异步和计划任务。
到目前为止,我只使用了带有 Celery + Celerybeat 的单个实例 Elastic Beanstalk 环境,并且效果非常好。但是,我想在我的环境中有多个实例 运行,因为时不时有一个实例崩溃并且需要很长时间才能备份该实例,但我无法将我当前的架构扩展到更多不是一个实例,因为 Celerybeat 应该在所有实例中只 运行 一次,否则 Celerybeat 计划的每个任务都将提交多次(环境中的每个 EC2 实例一次)。
我已经阅读了多种解决方案,但它们似乎都存在不适合我的问题:
- 使用 django 缓存 + 锁定:这种方法更像是一种快速修复,而不是真正的解决方案。如果您有很多计划任务并且需要添加代码来检查每个任务的缓存,那么这不是解决方案。此外,任务仍然会多次提交,这种方法只能确保重复项的执行停止。
- 将 leader_only 选项与 ebextensions 一起使用:最初工作正常,但如果环境中的 EC2 实例崩溃或被替换,这将导致根本没有 Celerybeat 运行 的情况,因为领导者只在创建环境时定义一次。
- 为 Elastic Beanstalk 工作层中的异步任务创建一个新的 Django 应用程序:很好,因为 Web 服务器和工作人员可以独立扩展,并且 Web 服务器性能不受工作人员执行的巨大异步工作负载的影响。但是,这种方法不适用于 Celery,因为工作层 SQS 守护程序会删除消息并将消息正文发布到预定义的 url。此外,我不喜欢拥有一个完整的附加 Django 应用程序的想法,该应用程序需要从主应用程序导入模型,并且如果在主应用程序中修改了任务,则需要单独更新和部署。
如何在分布式 Elastic Beanstalk 环境中将 Celery 与计划任务一起使用而不会重复任务?例如。我如何确保在 Elastic Beanstalk 环境中所有实例中始终只有一个实例 运行(即使使用 Celerybeat 的当前实例崩溃)?
还有其他方法可以实现吗?将 Elastic Beanstalk 的工作层环境与 Django 结合使用的最佳方式是什么?
万一有人遇到类似的问题:我最终切换到 django 的不同队列/任务框架。它被称为 django-q,在不到一个小时的时间内就完成了设置和工作。它具有我需要的所有功能,并且比 Celery 更好地集成了 Django(因为 djcelery 不再活跃)。
Django-q 超级易用,而且比庞大的 Celery 框架更轻巧。只能推荐了!
我猜你可以把 celery beat 分给不同的组。
您的自动缩放组运行多个 django 实例,但 celery 未包含在缩放组的 ec2 配置中。
你应该有不同的一组(或只有一组)celery beat 实例
我正在尝试找出构建 Django 应用程序的最佳方法,该应用程序使用 Celery 在自动扩展的 AWS ElasticBeanstalk 环境中处理异步和计划任务。
到目前为止,我只使用了带有 Celery + Celerybeat 的单个实例 Elastic Beanstalk 环境,并且效果非常好。但是,我想在我的环境中有多个实例 运行,因为时不时有一个实例崩溃并且需要很长时间才能备份该实例,但我无法将我当前的架构扩展到更多不是一个实例,因为 Celerybeat 应该在所有实例中只 运行 一次,否则 Celerybeat 计划的每个任务都将提交多次(环境中的每个 EC2 实例一次)。
我已经阅读了多种解决方案,但它们似乎都存在不适合我的问题:
- 使用 django 缓存 + 锁定:这种方法更像是一种快速修复,而不是真正的解决方案。如果您有很多计划任务并且需要添加代码来检查每个任务的缓存,那么这不是解决方案。此外,任务仍然会多次提交,这种方法只能确保重复项的执行停止。
- 将 leader_only 选项与 ebextensions 一起使用:最初工作正常,但如果环境中的 EC2 实例崩溃或被替换,这将导致根本没有 Celerybeat 运行 的情况,因为领导者只在创建环境时定义一次。
- 为 Elastic Beanstalk 工作层中的异步任务创建一个新的 Django 应用程序:很好,因为 Web 服务器和工作人员可以独立扩展,并且 Web 服务器性能不受工作人员执行的巨大异步工作负载的影响。但是,这种方法不适用于 Celery,因为工作层 SQS 守护程序会删除消息并将消息正文发布到预定义的 url。此外,我不喜欢拥有一个完整的附加 Django 应用程序的想法,该应用程序需要从主应用程序导入模型,并且如果在主应用程序中修改了任务,则需要单独更新和部署。
如何在分布式 Elastic Beanstalk 环境中将 Celery 与计划任务一起使用而不会重复任务?例如。我如何确保在 Elastic Beanstalk 环境中所有实例中始终只有一个实例 运行(即使使用 Celerybeat 的当前实例崩溃)?
还有其他方法可以实现吗?将 Elastic Beanstalk 的工作层环境与 Django 结合使用的最佳方式是什么?
万一有人遇到类似的问题:我最终切换到 django 的不同队列/任务框架。它被称为 django-q,在不到一个小时的时间内就完成了设置和工作。它具有我需要的所有功能,并且比 Celery 更好地集成了 Django(因为 djcelery 不再活跃)。
Django-q 超级易用,而且比庞大的 Celery 框架更轻巧。只能推荐了!
我猜你可以把 celery beat 分给不同的组。
您的自动缩放组运行多个 django 实例,但 celery 未包含在缩放组的 ec2 配置中。
你应该有不同的一组(或只有一组)celery beat 实例