首页 文章

在Elastic Beanstalk中运行cron作业

提问于
浏览
5

所以我在Django Elastic Beanstalk应用程序中有一个功能如下:

  • 下载文件

  • 解析文件,使用文件中的数据运行对API的一些调用

  • 使用新数据更新EB实例的数据库

在我刚刚设置本地cron作业的测试实例中 . 我刚刚在我的Django应用程序的特定URL上调用了 wget ,它将运行该命令 .

我的问题是如何在多实例Elastic Beanstalk应用程序中处理这个问题 . 我的EB应用程序只有一个实例应该运行此命令 . 我想避免数据库上的竞争条件和多个实例对外部API的冗余调用 . 即只有一个实例应该写入数据库 .

然而,谷歌搜索显示设置cron工作是很尴尬的,特别是如果你像我这样的新EB . 最有希望的声音方法似乎是 cron.yaml 方法,但似乎没有一个例子可以在我看到的网络上的任何地方设置一个cron worker环境 .

我的理解是:

  • 您在EB项目的根目录中包含cron.yaml文件 .

  • 部署项目

  • cron作业在工作环境中自动设置(?) .

  • 您定义的命令在指定的时间运行 .

我的问题是你如何确保只有一个实例将运行此命令?我是否对 cron.yaml 的工作方式有正确的认识,或者是否有我遗漏的东西

1 回答

  • 3

    只有一个实例将运行该命令,因为cron作业实际上并不在cron守护程序中运行 .

    很少有概念可以帮助您快速了解亚马逊的Elastic Beanstalk心态 .

    • 弹性beanstalk环境必须选择一个必须只有一个的领导者实例(它必须是一个 Health 的实例等) .

    • 工作线程环境通过SQS(简单队列服务)队列分配工作 .

    • 从队列中读取消息后,它将被视为'in-flight',直到工作人员返回200或请求超时/失败 . 在第一个场景中,消息被删除,在后一个场景中,它重新进入队列 . (Redrive策略可以确定消息在发送到死信队列之前失败的次数)

    • 无法再次读取飞行中的消息(除非返回) .

    队列中的消息一次只能被工作环境中的一个实例拾取一次 .

    现在 cron.yaml 文件实际上只是告诉领导者在计划中指定的时间在队列中创建具有特殊属性的消息 . 然后,当它找到此消息时,它仅作为对指定URL的POST请求被分派到一个实例 .

    当我在工作环境中使用Django时,我创建了一个 cron 应用程序,其中包含映射到我想要的操作的视图 . 例如,如果我想定期轮询Facebook endpoints ,我可能有一个路径 /cron/facebook/poll/ ,它在views.py中调用 poll_facebook() 函数

    这样,如果我有一个如下的cron.yaml,它将每小时轮询Facebook一次:

    version: 1
    cron:
     - name: "pollfacebook"
       url: "/cron/facebook/poll/"
       schedule: "0 * * * *"
    

相关问题