AWS 中的自动缩放服务,无需复制 cron 作业

Auto scaling service in AWS without duplicating cron jobs

我在 EC2 上的 AWS 上有一个(golang 网络服务器)服务 运行(无自动缩放)。此服务有几个全天运行的 cron 作业,这些作业在服务启动时启动。

我想在 AWS 上以某种形式利用 Auto Scaling。一直在关注 ECS 和 Beanstalk。

当我添加自动缩放时,由于外部 API 的速率限制,我需要 cron 作业仅在其中一项缩放服务上执行。现在 cron 作业在服务中紧密耦合,我正在寻找不需要将 cron 作业移动到它自己的服务的选项。

如何使用 AWS 以好的方式实现这一目标?

在 crons 不能/不应该 运行 多次的任何可伸缩应用程序中,您将把这个问题作为一个普遍问题。它并不是特定于 AWS 的。我不确定你希望在多大程度上保持耦合,或者你的 crons 目前如何 运行 但这里有一些可能对你有用的建议:

创建一个“cron 运行ner”实例,限制为运行 crons on

您可以创建一个单独的 ECS 服务,它没有自动缩放和 1 个实例的固定值。该实例将 运行 与您的“正常”实例相同的代码副本,并且将 运行 crons。你会在你的“正常”实例上关闭 crons。您可能会发现这可能是一个非常小的实例,因为它不处理任何网络流量。

创建一个远程触发 crons 的“cron 触发器”实例

在这里您创建一个“触发器”实例,它通过 ALB 向您的普通实例发送请求。因为您的 ALB 会将请求路由到它后面的其中一台服务器,所以 cron 只获得 运行 一次。需要注意的是,如果您的 cron 很长 运行ning,您可能需要考虑您的请求超时。您还必须考虑重试等,但我假设您已经有一个可以适应的过程。


上述解决方案可以适用于消息队列等,但两者的基础是有另一个启动 cron 的实例,并且与您的普通服务器分开。根据你的 cron 运行s 的时间,你可能只需要每天 运行 这个 cron 实例几个小时,这样做这样的事情会很划算。

就个人而言,我在多租户应用程序中使用了这两种方法,由于租户的数量和它花费的时间/资源,我不得不选择 运行 像这样设置 cron 运行 一次为他们所有人的 crons:

  • Cloudwatch 计划触发一个 lambda,它向 SQS 发送一条消息,为每个租户单独排队一个 cron。
  • Cron 服务器(完全独立于主要 Web 服务器,但 运行 使用相同/相似的代码)分别为每个租户提取消息和 运行 cron。在 redis 中为 crons 存储一个密钥,这对于仅 运行 一次停止“至少一次”交付的问题至关重要,因此 crons 不会 运行 两次。

这也有助于处理在 SQS 中管理的重试策略和死信队列的故障。

最终你需要从一个地方启动这些crons。如果可能,请更改您的 cron,这样即使它们 运行 两次也没关系。它可以更轻松地处理重试和类似的事情。