【问题标题】:AWS EC2: How to prevent infinite loop for instance status check?AWS EC2:如何防止实例状态检查的无限循环?
【发布时间】:2016-05-19 21:04:59
【问题描述】:

我有以下 python boto3 代码,可能是无限的while-loop。通常,几分钟后while-loop 会成功。但是,如果 AWS 端出现故障,程序可能会无限期挂起。

我确信这不是最合适的方式。

# credentials stored in ../.aws/credentials
# region stored in ../.aws/config

# builtins
from time import sleep
# plugins
import boto3

# Assign server instance IDs.
cye_production_web_server_2 = 'i-FAKE-ID'

# Setup EC2 client
ec2 = boto3.client('ec2')

# Start the second web server.
start_response = ec2.start_instances(
    InstanceIds=[cye_production_web_server_2, ],
    DryRun=False
)

print(
    'instance id:',
    start_response['StartingInstances'][0]['InstanceId'],
    'is',
    start_response['StartingInstances'][0]['CurrentState']['Name']
)

# Wait until status is 'ok'
status = None
while status != 'ok':
    status_response = ec2.describe_instance_status(
        DryRun=False,
        InstanceIds=[cye_production_web_server_2, ],
    )
    status = status_response['InstanceStatuses'][0]['SystemStatus']['Status']
    sleep(5)    # 5 second throttle

print(status_response)
print('status is', status.capitalize())

【问题讨论】:

    标签: python python-3.x amazon-web-services amazon-ec2 boto3


    【解决方案1】:

    在循环中实现一个计数器并在多次尝试后失败

    status = None
    counter = 5
    while (status != 'ok' and counter > 0):
        status_response = ec2.describe_instance_status(
            DryRun=False,
            InstanceIds=[cye_production_web_server_2, ],
        )
        status = status_response['InstanceStatuses'][0]['SystemStatus']['Status']
        sleep(5)    # 5 second throttle
        counter=counter-1
    
    print(status_response)
    print('status is', status.capitalize())
    

    【讨论】:

      【解决方案2】:

      您可以尝试在for 循环中执行此操作,而不是使用固定次数的尝试。

      例如:

      MAX_RETRIES = 5
      
      # Try until status is 'ok'
      for x in range(MAX_RETRIES):
          status_response = ec2.describe_instance_status(
              DryRun=False,
              InstanceIds=[cye_production_web_server_2, ],
          )
          status = status_response['InstanceStatuses'][0]['SystemStatus']['Status']
          if status != 'ok':
              sleep(5)    # 5 second throttle
          else:
              break
      

      【讨论】:

      • 好的,所以 5 次重试转换为 (5sec * 5retries = 25 秒),我可以增加或减少这个值。在这种情况下是否有理由不使用 while 循环。 for 循环(在这种情况下似乎更冗长)。
      • 它有点冗长,这是真的。您可以按照其他响应者的建议使用 while 循环,这也可以。不使用while循环的原因是为了防止陷入你描述的无限循环
      【解决方案3】:

      使用超时可能是一个更好的主意

      import time 
      
      systemstatus = False
      timeout = time.time() + 60*minute
      
      while systemstatus is not True:
          status = ec2.describe_instance_status( \
                       DryRun = False,
                       InstanceIds = [instance_id]
                   )
      
          if status['InstanceStatuses'][0]['SystemStatus']['Status'] == 'ok':
              systemstatus = True
      
          if time.time() > timeout:
              break
          else:
              time.sleep(10)
      

      【讨论】:

        猜你喜欢
        • 2020-01-09
        • 2021-07-23
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 2019-12-16
        • 2020-01-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多