【问题标题】:How do I know if instance is ready to be invoked?我如何知道实例是否已准备好被调用?
【发布时间】:2022-01-02 16:47:13
【问题描述】:

我编写了以下代码来启动AWS Instance。它工作正常。我能够启动AWS 实例。但我需要等待,直到实例的状态检查为2/2 或实例已准备好被调用。

public function launch_instance() {
    $isInstanceLaunched = array('status' => false);
    try {
        if(!empty($this->ec2Client)) {
            /**
             * 1) EbsOptimized : Indicates whether the instance is optimized for EBS I/O. 
             * This optimization provides dedicated throughput to Amazon EBS and an optimized 
             * configuration stack to provide optimal EBS I/O performance. This optimization isn't 
             * available with all instance types. Additional usage charges apply when using an 
             * EBS-optimized instance.
             */
            $result = $this->ec2Client->runInstances([
                    'AdditionalInfo' => 'Launched from API',
                    'DisableApiTermination' => false,
                    'ImageId' => 'ami-8xaxxxe8', // REQUIRED
                    'InstanceInitiatedShutdownBehavior' => 'stop',
                    'InstanceType' => 't2.micro',
                    'MaxCount' => 1, // REQUIRED
                    'MinCount' => 1, // REQUIRED,
                    'EbsOptimized' => false, // SEE COMMENT 1
                    'KeyName' => 'TestCloudKey',
                    'Monitoring' => [
                            'Enabled' => true // REQUIRED
                    ],
                    'SecurityGroups' => ['TestGroup']
            ]);

            if($result) {
                $metadata = $result->get('@metadata');
                $statusCode = $metadata['statusCode'];
                //Verify if the code is 200
                if($statusCode == 200) {
                    $instanceData = $result->get('Instances');
                    $instanceID = $instanceData[0]['InstanceId'];
                    // Give  a name to the launched instance
                    $tagCreated = $this->ec2Client->createTags([
                            'Resources' => [$instanceID],
                            'Tags' => [
                                    [
                                            'Key' => 'Name',
                                            'Value' => 'Created from API'
                                    ]
                            ]
                    ]);
                    $instance = $this->ec2Client->describeInstances([
                            'InstanceIds' => [$instanceID]
                    ]);
                    $instanceInfo = $instance->get('Reservations')[0]['Instances'];
                    // Get the Public IP of the instance
                    $instancePublicIP = $instanceInfo[0]['PublicIpAddress'];
                    // Get the Public DNS of the instance
                    $instancePublicDNS = $instanceInfo[0]['PublicDnsName'];
                    // Get the instance state
                    $instanceState = $instanceInfo[0]['State']['Name'];
                    $instanceS = $this->ec2Client->describeInstanceStatus([
                            'InstanceIds' => [$instanceID]
                    ]);
                    try {
                        $waiterName = 'InstanceRunning';
                        $waiterOptions = ['InstanceId' => $instanceID];
                        $waiter = $this->ec2Client->getWaiter($waiterName,$waiterOptions);
                        // Initiate the waiter and retrieve a promise.
                        $promise = $waiter->promise();
                        // Call methods when the promise is resolved.
                        $promise
                        ->then(function () {
                            // Waiter Completed
                        })
                        ->otherwise(function (\Exception $e) {
                            echo "Waiter failed: " . $e . "\n";
                        });
                        // Block until the waiter completes or fails. Note that this might throw
                        // a RuntimeException if the waiter fails.
                        $promise->wait();
                    }catch(RuntimeException $runTimeException) {
                        $isInstanceLaunched['side-information'] = $runTimeException->getMessage();
                    }   
                    $isInstanceLaunched['aws-response'] = $result;
                    $isInstanceLaunched['instance-public-ip'] = $instancePublicIP;
                    $isInstanceLaunched['status'] = true;
                }   
            }               
        }else {
            $isInstanceLaunched['message'] = 'EC2 client not initialized. Call init_ec2 to initialize the client';
        }
    }catch(Ec2Exception $ec2Exception){
        $isInstanceLaunched['message'] = $ec2Exception->getMessage().'-- FILE --'.$ec2Exception->getFile().'-- LINE --'.$ec2Exception->getLine();
    }catch(Exception $exc) {
        $isInstanceLaunched['message'] = $exc->getMessage().'-- FILE -- '.$exc->getFile().'-- LINE -- '.$exc->getLine();
    }

    return $isInstanceLaunched;
}

我使用了名为InstanceRunningwaiter,但这并没有帮助。我如何知道实例已准备好被调用或状态检查为2/2

【问题讨论】:

    标签: php amazon-web-services amazon-ec2 aws-sdk


    【解决方案1】:

    你有没有尝试替换

    $waiter = $this->ec2Client->getWaiter($waiterName,$waiterOptions);
    

    $this->ec2Client->waitUntil($waiterName, $waiterOptions);          
    $result = $ec2->describeInstances(array(
                    'InstanceIds' => array($instanceId),
                ));
    

    我有一段时间没有测试,但它曾经对我有用

    【讨论】:

      【解决方案2】:

      您需要使用两个服务员:首先是“InstanceRunning”,然后是“InstanceStatusOk”

      【讨论】:

      • 非常感谢您的评论,这正是我的问题
      【解决方案3】:

      我编写了以下代码来检查实例是否已准备好被调用。我做了一个polling 来检查statusCheck 是否是ok

          /**
           * The following block checks if the instance is ready to be invoked
           * or StatusCheck of the instance equals 2/2
           * Loop will return:
           *  - If the status check received is 'ok'
           *  - If it exceeds _amazon_client::MAX_ATTEMPTS_TO_EC2_SCHECK
           */
      
          $statusCheckAttempt = 0;
          do {
              // Sleep for _amazon_client::POLLING_SECONDS
              sleep(_amazon_client::POLLING_SECONDS);
              // Query the instance status
              $instanceS = $this->ec2Client->describeInstanceStatus([
                      'InstanceIds' => [$instanceID]
              ]);
              $statusCheck = $instanceS->get('InstanceStatuses')[0]['InstanceStatus']['Status'];
              $statusCheckAttempt++;
          }while($statusCheck != 'ok' || 
                  $statusCheckAttempt >= _amazon_client::MAX_ATTEMPTS_TO_EC2_SCHECK);
      

      注意:当实例刚刚启动时,$instanceS->get('InstanceStatuses')[0] 返回一个空数组。所以我等了几秒钟,然后才能真正获得状态。

      请建议是否有更好的方法来实现这一点。

      【讨论】:

        猜你喜欢
        • 2019-10-11
        • 2012-10-19
        • 2011-06-01
        • 1970-01-01
        • 2019-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-12
        相关资源
        最近更新 更多