Amazon web services 我可以用lambda函数计划lambda函数的执行吗?

Amazon web services 我可以用lambda函数计划lambda函数的执行吗?,amazon-web-services,aws-lambda,Amazon Web Services,Aws Lambda,我希望能够通过编程方式安排一个lambda函数与另一个lambda函数一起运行一次。例如,我使用date和time参数请求myFirstFunction,然后在该日期和时间执行mySecondFunction。只有无状态的AWS服务才有可能做到这一点吗?我正试图避免一个总是在ec2上的实例 我发现调度lambda函数的大多数结果都与cloudwatch和定期调度的事件有关,而不是临时事件。我选择将延迟的工作排队给SQS,在myFirstFunction中使用 目前,您不能将SQS用作Lambda

我希望能够通过编程方式安排一个lambda函数与另一个lambda函数一起运行一次。例如,我使用
date
time
参数请求
myFirstFunction
,然后在该日期和时间执行
mySecondFunction
。只有无状态的AWS服务才有可能做到这一点吗?我正试图避免一个总是在ec2上的实例


我发现调度lambda函数的大多数结果都与cloudwatch和定期调度的事件有关,而不是临时事件。

我选择将延迟的工作排队给SQS,在myFirstFunction中使用


目前,您不能将SQS用作Lambda事件源,但您可以定期安排mySecondFunction,通过安排的CloudWatch事件(某种程度上是您发现的其他选项的变体)检查队列或者使用上的CloudWatch警报向Lambda发送SNS消息,避免对经常长时间处于非活动状态的队列进行持续轮询

更新-我不建议使用这种方法。当TTL删除发生并且它们不接近TTL时间时,情况发生了变化。唯一的保证是该项目将在TTL之后删除。感谢@Mentor强调这一点

2个月前,AWS发布了DynamoDB item TTL,允许您插入一个项目,并在希望删除该项目时进行标记。到时候它会自动删除

您可以将此功能与DynamoDB Streams结合使用以实现您的目标—您的第一个函数将向DynamoDB表插入一个项。记录TTL应该在您希望触发第二个lambda时出现。设置一个触发第二个lambda的流。在此lambda中,您将识别删除事件,如果是删除事件,则运行逻辑

奖励点-您可以使用表项作为第一个lambda向第二个lambda传递参数的机制

关于DynamoDB TTL:

您要做的事情(从Lambda计划Lambda)在当前的AWS服务中是不可能的

因此,为了避免始终开启ec2实例,还有其他选项:

1) 使用AWS默认或自定义指标。例如,您可以使用或(如果您的应用程序在处理请求时占用大量CPU)。您还可以创建自定义度量,并在实例空闲时触发它(取决于实例中运行的应用程序)

此选项的问题是,您将浪费已经付费的分钟数(AWS始终收取一小时的费用,无论您是否使用实例15分钟)

2) 在我看来,一个更好的选择是每分钟运行一次Lambda函数来检查实例是否空闲,并且只有当它们接近一小时时才关闭它们

import boto3
from datetime import datetime

def lambda_handler(event, context):
    print('ManageInstances function executed.')
    environments = [['instance-id-1', 'SQS-queue-url-1'], ['instance-id-2', 'SQS-queue-url-2'], ...]
    ec2_client = boto3.client('ec2')
    for environment in environments:
        instance_id = environment[0]
        queue_url = environment[1]
        print 'Instance:', instance_id
        print 'Queue:', queue_url
        rsp = ec2_client.describe_instances(InstanceIds=[instance_id])
        if rsp:
            status = rsp['Reservations'][0]['Instances'][0]
            if status['State']['Name'] == 'running':
                current_time = datetime.now()
                diff = current_time - status['LaunchTime'].replace(tzinfo=None)
                total_minutes = divmod(diff.total_seconds(), 60)[0]
                minutes_to_complete_hour = 60 - divmod(total_minutes, 60)[1]
                print 'Started time:', status['LaunchTime']
                print 'Current time:', str(current_time)
                print 'Minutes passed:', total_minutes
                print 'Minutes to reach a full hour:', minutes_to_complete_hour
                if(minutes_to_complete_hour <= 2):
                    sqs_client = boto3.client('sqs')
                    response = sqs_client.get_queue_attributes(QueueUrl=queue_url, AttributeNames=['All'])
                    messages_in_flight = int(response['Attributes']['ApproximateNumberOfMessagesNotVisible'])
                    messages_available = int(response['Attributes']['ApproximateNumberOfMessages'])
                    print 'Messages in flight:', messages_in_flight
                    print 'Messages available:', messages_available
                    if(messages_in_flight + messages_available == 0):
                        ec2_resource = boto3.resource('ec2')
                        instance = ec2_resource.Instance(instance_id)
                        instance.stop()
                        print('Stopping instance.')
            else:
                print('Status was not running. Nothing is done.')
        else:
            print('Problem while describing instance.')
导入boto3
从日期时间导入日期时间
def lambda_处理程序(事件、上下文):
打印('已执行ManageInstances函数')
环境=['instance-id-1','SQS-queue-url-1',['instance-id-2','SQS-queue-url-2'],…]
ec2_client=boto3.client('ec2')
对于环境中的环境:
实例\u id=环境[0]
队列url=环境[1]
打印“实例:”,实例id
打印“队列:”,队列url
rsp=ec2\u客户端。描述\u实例(instanceId=[instance\u id])
若为可吸入悬浮粒子:
状态=rsp['Reservations'][0]['Instances'][0]
如果状态['State']['Name']=='running':
当前时间=datetime.now()
diff=当前时间-状态['LaunchTime']。替换(tzinfo=无)
总分钟=divmod(差异总秒数(),60)[0]
分钟到完成小时=60-divmod(总分钟,60)[1]
打印“开始时间:”,状态[“启动时间”]
打印“当前时间:”,str(当前时间)
打印“通过的分钟数:”,总分钟数
打印“达到完整小时的分钟数:”,分钟数到完整小时数

if(minutes\u to\u complete\u hour这取决于您的用例,但您希望在以后触发某个事件的想法是一种常见的模式。我在无服务器情况下执行此操作的方式是,我有一个react应用程序,该应用程序触发一个操作以存储将来的日期。我采用24-12-2020之类的日期格式,然后使用date()将其转换为,在研究了上述日期格式是否正确后,我可能会尝试12-24-2020,看看我得到了什么(!)。当我高兴时,我会将其转换为javascript React中的Unix数字,我使用以下代码:

new Date(action.data).getTime() / 1000
其中action.data是操作的日期和时间

我在Amplify(serverless)中运行React,将其存储到dynamodb(serverless)。然后运行Lambda函数(serverless)检查我的dynamodb是否有任何日期(我现在实际上使用Unix时间),并时不时地比较两个Unix日期(存储)这两个都是数字,所以比较容易。在我看来,这非常容易,也非常可靠

我只是将Lambda上的crontab设置为所需的任意值,具体取决于所需的近似频率,在大多数情况下,每五分钟运行一次Lambda是相当不错的,尽管如果我只是在某个时区为一个商业工作日应用程序操作它,我会对Lambda进行多一点控制。Lambda在第一个时间段是免费的每月一次,每隔几分钟运行一次,将不会产生任何成本。显然,情况会发生变化,所以您需要在您所在的区域查找

在这种情况下,您永远不会获得完美的计时。但是,对于绝大多数用例,根据Lambda函数的计时设置,您可以将其设置为每分钟检查一次或每天检查一次,这完全取决于您的应用程序


或者,如果我想对某个事件做出即时反应,我可能会使用SMS、SQS或Kinesis来即时传递消息,这完全取决于您的用例。

这是一个非常适合您的用例

美国