在Elastic Beanstalk中运行cron作业

时间:2016-07-22 09:34:49

标签: python django amazon-web-services cron elastic-beanstalk

所以我在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 个答案:

答案 0 :(得分:3)

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

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

  • 弹性beanstalk环境必须选择一个必须只有一个的领导者实例(并且它必须是一个健康的实例等)。
  • 工作线程环境通过SQS(简单队列服务)队列分配工作。
  • 从队列中读取消息后,它将被视为“正在进行中”,直到工作人员返回200或请求超时/失败。在第一个场景中,消息被删除,在后一个场景中,它重新进入队列。 (Redrive策略可以确定消息在发送到死信队列之前失败的次数)
  • 在飞行中无法再次阅读消息(除非已退回)。

队列中的消息一次只能通过工作环境中一个的实例获取一次。

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

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

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

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