您想要做的事情(从 Lambda 调度 Lambda)使用当前的 AWS 服务是不可能的。
因此,为了避免永远在线的 ec2 实例,还有其他选择:
1) 使用 AWS 默认或自定义指标。例如,您可以使用ApproximateNumberOfMessagesVisible 或CPUUtilization(如果您的应用程序在处理请求时触发大量 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.')