首页 文章

我可以使用lambda函数安排lambda函数执行吗?

提问于
浏览
5

我正在寻找以编程方式安排lambda函数与另一个lambda函数运行一次的能力 . 例如,我使用 datetime 参数向 myFirstFunction 发出请求,然后在该日期和时间执行 mySecondFunction . 这只能用于无状态AWS服务吗?我试图避免一个永远在线的ec2实例 .

我发现用于调度lambda函数的大多数结果都与cloudwatch和定期调度的事件有关,而不是ad-hoc事件 .

5 回答

  • 0

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

    2个月前,AWS宣布了DynamoDB项目TTL,它允许您插入项目并在希望删除时标记 . 它会在时机成熟时自动删除 .

    您可以将此功能与DynamoDB Streams结合使用以实现您的目标 - 您的第一个功能是将项目插入DynamoDB表 . 记录TTL应该是您想要触发第二个lambda的时间 . 设置一个触发你的第二个lambda的流 . 在这个lambda中,您将识别删除事件,如果这是删除,则运行您的逻辑 .

    加分点 - 您可以使用表项作为第一个lambda将参数传递给第二个lambda的机制 .

    关于DynamoDB TTL:https://aws.amazon.com/blogs/aws/new-manage-dynamodb-items-using-time-to-live-ttl/

  • 1

    您要做的事情(从Lambda安排Lambda)当前的AWS服务是不可能的 .

    因此,为了避免永远在线的ec2实例,还有其他选择:

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

    此选项的问题在于您将浪费已支付的分钟数(无论您是否使用实例15分钟,AWS总是收取一整小时的费用) .

    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.')
    
  • 0

    我想也许你可以使用these instructions .

    但除非我手动进入控制台以将规则与目标链接,否则我将无法工作 . (尽管发送了API调用 put_target

    另外,我不明白这些说明的最后一步是什么 . 我没有这样做,因为它似乎不适用,但也许这就是我不工作的原因 .

  • 0

    如果要同时运行第二个函数,请使用AWS SDK的 invoke()Lambda 方法 . 使用调用类型 Event ,您可以调用并忘记 .

    如果要在几分钟后运行第二个函数,则应安排lambda函数使用CloudWatch Events规则每隔x分钟运行一次,但禁用该规则 . 在第一个函数中,使用AWS SDK的 CloudWatchEvents 类的 enableRule() 方法以编程方式启用规则 . 在预定的功能中,选中使用 enableRule() 禁用自身 .

  • 0

    我选择在myFirstFunction中使用message timers将延期工作排入SQS .

    目前,您可以't use SQS as a Lambda event source, but you can either periodically schedule mySecondFunction to check the queue via scheduled CloudWatch Events (somewhat of a variant of the other options you'发现)或使用ApproximateNumberOfMessagesVisible上的CloudWatch警报向S小部件发送SNS消息,并避免对经常长时间处于非活动状态的队列进行持续轮询 .

相关问题