0

我正在开发一个项目,该项目作为具有 3 个副本的服务部署在 docker swarm 上。如果日期已过,我想运行一个简单的管理命令从表中删除一些行。我已经为它编写了一个 django 命令,但是想使用 cron 作业使运行自动化。我确实想确保作业每天仅从属于我的服务的任何容器运行一次。在互联网上,我发现了一些为 Django 应用程序运行 cron 作业而构建的包,但它们都没有考虑多个容器。一些包有基于锁的方法,但它是基于文件的锁而不是共享锁。我不想用芹菜来完成这个简单的任务。

以下是我的命令的一瞥:


class Command(BaseCommand):
    """Command to clear user subscription if end_date has passed"""

    def handle(self, *args, **options):
        try:
            deleted_count, relative_deleted = MyModel.delete_inactive_instances()
        except Exception:
            raise CommandError('Could Not Remove Inactive Subscriptions From DB')
        else:
            self.stdout.write(self.style.SUCCESS('Successfully Removed Inactive Subscriptions %s ' % deleted_count))

我目前每天都通过 docker exec 运行一个命令:

python manage.py delete_inactive_instances

以下是我的 docker-stack 文件:

services:
  production_app:
    image: {id}.dkr.ecr.{region}.amazonaws.com/xxxxxx:latest
    expose:
      - 8000
    deploy:
      replicas: 2
    command: >
        sh -c "python manage.py migrate && gunicorn app.wsgi:application --workers 3 --bind 0.0.0.0:8000"
    env_file:
      - .prod.env

  nginx:
    image: {id}.dkr.ecr.{region}.amazonaws.com/nginx:latest
    ports:
      - 80:80

4

2 回答 2

1

您可以使用 Celery 和 Celery Beat 调度程序。它与 Django 完美集成。在您的 docker swarm 配置中,您将添加以下服务:

  • 芹菜节拍调度器:1个副本
  • 一个芹菜工人:你想要多少复制品
  • redis(用于消息代理)

如果你不想为你的 swarm 添加额外的服务,你也可以在你的 django 容器中运行 celery workers 作为后台任务。节拍调度程序是控制任务何时运行的调度程序,但它们实际上是由 celery 工作人员执行的

您可以在此项目中找到使用 docker compose 配置进行工作设置的示例: https ://github.com/testdrivenio/django-celery-beat

作为替代方案,您可以在堆栈配置中使用相同的图像但不同的入口点定义一个附加服务:该服务将只负责运行由入口点定义的 cron 任务

于 2020-10-11T00:52:52.147 回答
0

您可以使用 Celery 和 Celery Beat 调度程序。它与 Django 完美集成。在您的 docker swarm 配置中,您将添加以下服务:

  • 芹菜节拍调度器:1个副本
  • 一个芹菜工人:你想要多少复制品
  • redis(用于消息代理)

如果你不想为你的 swarm 添加额外的服务,你也可以在你的 django 容器中运行 celery workers 作为后台任务。但是,您应该只运行节拍调度程序的一个实例以防止任务重复。节拍调度程序是控制任务何时运行的调度程序,但它们实际上是由 celery 工作人员执行的。

您可以在此处找到 docker compose 配置的示例: https ://github.com/testdrivenio/django-celery-beat

于 2020-10-11T00:40:39.320 回答