我正在寻找以编程方式安排lambda函数与另一个lambda函数运行一次的能力。例如,我使用myFirstFunction
和date
参数向time
发出了请求,然后在该日期和时间执行mySecondFunction
。这只能用于无状态AWS服务吗?我试图避免一个永远在线的ec2实例。
我发现调度lambda函数的大部分结果都与cloudwatch和定期调度的事件有关,而不是ad-hoc事件。
答案 0 :(得分:3)
这是 aws step functions 的完美用例。
将 Wait
状态与 SecondsPath
或 TimestampPath
结合使用以在执行下一个状态之前添加所需的延迟。
答案 1 :(得分:1)
更新 - 我不建议使用这种方法。当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/
答案 2 :(得分:1)
如果您想同时运行第二个功能,请使用AWS开发工具包的invoke()
类的Lambda
方法。使用调用类型Event
时,您会忘记通话。
如果要在几分钟后运行第二个函数,则应使用CloudWatch Events规则安排lambda函数每隔x分钟运行一次,但请禁用该规则。在第一个函数中,使用enableRule()
类的AWS开发工具包的CloudWatchEvents
方法以编程方式启用规则。然后在预定的函数中,选中enableRule()
来禁用自身。
答案 3 :(得分:0)
我选择在myFirstFunction中使用message timers将延期工作排入SQS。
目前,您不能将SQS用作Lambda事件源,但您可以定期安排mySecondFunction通过计划的CloudWatch Events检查队列(有些是您找到的其他选项的变体)或使用CloudWatch在ApproximateNumberOfMessagesVisible上发出警报以向Lambda发送SNS消息,并避免对长时间不经常处于非活动状态的队列进行持续轮询。
答案 4 :(得分:0)
您要做的事情(从Lambda安排Lambda)使用当前的AWS服务是不可能的。
因此,为了避免永远在线的ec2实例,还有其他选择:
1)使用AWS默认或自定义指标。例如,您可以使用ApproximateNumberOfMessagesVisible或CPUUtilization(如果您的应用在处理请求时触发大量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.')
答案 5 :(得分:0)
我想也许你可以使用these instructions。
但我已尝试过这些说明,除非我手动进入控制台将规则与目标相关联,否则它无法正常工作。 (尽管发送了API调用put_target
)
另外,我不明白这些说明的最后一步是什么。我没有这样做,因为它似乎不适用,但也许这就是为什么我的工作不起作用。
答案 6 :(得分:0)
这的确取决于您的用例,但是您想稍后触发某事的想法是一种常见的模式。我无服务器的方式是有一个React应用程序,该应用程序会触发将来存储日期的操作。我采用了类似于24-12-2020的日期格式,然后使用date()对其进行了转换,研究了提到的日期格式是正确的,因此我可以尝试使用12-24-2020看看我得到了什么!当我高兴时,我将其转换为javascript React中的Unix编号,我使用以下代码:
new Date(action.data).getTime() / 1000
其中action.data是操作的日期,也许是时间。
我在Amplify(无服务器)中运行React,然后将其存储到dynamodb(无服务器)中。然后,我运行Lambda函数(无服务器)以检查我的dynamodb是否存在任何日期(我现在实际使用Unix时间),然后立即比较这两个Unix日期(存储的),它们都是数字,因此比较容易。在我看来,这是非常容易且非常可靠的。
我只是根据所需的近似频率将Lambda上的crontab设置为所需的值,在大多数情况下,每五分钟运行一次Lambda是相当不错的,尽管如果我只是在某个特定时间段内进行业务操作平日的应用程序,我将控制Lambda多一点。 Lambda每月免费提供前100万个功能,每隔几分钟运行一次Lambda无需花费任何费用。显然情况发生了变化,因此您需要在您所在的地区进行查找。
在这种情况下,您永远不会获得完美的时机。但是,由于根据Lambda函数的计时设置,绝大多数用例都足够接近,因此您可以将其设置为每分钟或每天检查一次,这完全取决于您的应用程序。
或者,如果我想对事件进行即时反应,则可以使用SMS,SQS或Kinesis即时流式传输消息,这完全取决于您的用例。