ECS/Fargate - 我可以每 5 分钟安排一个工作到 运行 除非它已经 运行ning 了吗?

ECS/Fargate - can I schedule a job to run every 5 minutes UNLESS its already running?

我有一项 ECS/Fargate 任务,每五分钟 运行 一次。如果先前的实例仍在工作,有没有办法告诉它不要 运行?目前我只是向它传递一个 cron 表达式,cron/rate aws 文档中没有任何关于阻止后续 运行s.

的内容

从概念上讲,我正在寻找类似于 Spring 的 @Scheduled(fixedDelay=xxx) 的东西,它会在完成后每五分钟 运行。

编辑 - 我使用 cloudformation 创建了任务,而不是 cli

如果您使用 CLI 启动任务,运行-task 命令将为您 return 执行任务。

然后您可以使用它来检查该任务的状态:

aws ecs describe-tasks --cluster MYCLUSTER --tasks TASK-ARN --query 'tasks[0].lastStatus'

它会 return RUNNING 如果它仍然 运行 宁,STOPPED 如果停止等

请注意,Fargate 非常积极地收集已停止的任务。如果那个命令returnsnull,可以考虑STOPPED.

如果您为 ECS 应用程序使用 Cloudwatch 日志记录,则此解决方案有效 - 让您的脚本发出 'task completed' 或 'script successfully completed running' 消息,以便您稍后可以跟踪它。

  • 使用describeLogStreams函数,首先检索最新的日志流。在您的案例中,这将是为 运行 5 分钟前的任务创建的流。
  • 获得流的名称后,检查最后几个记录的事件(流中打印的文本)以查看它是否是您的流应该打印的预期任务完成事件。为此使用 getLogEvents 函数。
  • 如果不是,则不要启动下一个任务并根据需要调用等待或句柄
  • 像往常一样将您的脚本安排为每 5 分钟 运行。

API aws-sdk 文档的链接如下。此脚本是用 JS 编写的,并使用 AWS-SDK (https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS.html),但您可以将 boto3 用于 python,或将不同的库用于其他语言

    const logGroupName = 'logGroupName';
    this.cloudwatchlogs = new AwsSdk.CloudWatchLogs({
       apiVersion: '2014-03-28', region: 'us-east-1'
    });

 // Get the latest log stream for your task's log group. 
 // Limit results to 1 to get only one stream back.

    var descLogStreamsParams = {
      logGroupName: logGroupName,
      descending: true,
      limit: 1,
      orderBy: 'LastEventTime'
    };

    this.cloudwatchlogs.describeLogStreams(descLogStreamsParams, (err, data) => {

      // Log Stream for the previous task run..

      const latestLogStreamName = data.logStreams[0].logStreamName;

      // Call getLogEvents to read from this log stream now..

      const getEventsParams = {
        logGroupName: logGroupName,
        logStreamName: latestLogStreamName,
      };

      this.cloudwatchlogs.getLogEvents(params, (err, data) => {

        const latestParsedMessage = JSON.parse(data.events[0].message); 

        // Loop over this to get last n messages
        // ...
      });
    });