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
// ...
});
});
我有一项 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
// ...
});
});