2016-08-17 295 views
0

我想在新用戶到達時創建ec2實例。我創建了一個servlet類來執行此操作。當用戶到達時,我檢查DB是新用戶還是不新用戶,然後創建實例併發回他/她的IP。當我向用戶發送http請求到這個servlet一個接一個,我正確地得到IP。但是,當我並行發送HTTP調用(對於user1發送請求在tab1中,對於user2同時發送請求在tab2中獲得來自user1 HTTP調用的響應之前)。當我這樣做時,我得到了錯誤。有時USER1說AWS EC2實例:啓動多個實例

「實例ID 'I-0b79495934c3b5459' 不存在(服務: AmazonEC2;狀態代碼:400;錯誤代碼:InvalidInstanceID.NotFound; 請求ID:e18a9eaa-cb1b-4130-a3ee -bf1b19fa184c)「

並且user2發送IP作爲響應。請幫助我解決問題的方法和方法。 這是我創建的Servlet類。

public class GateKeeperController extends HttpServlet { 
    private static final long serialVersionUID = 1L; 
    BasicAWSCredentials awsCreds = new BasicAWSCredentials(credentials); 
    AmazonEC2Client ec2Client = new AmazonEC2Client(awsCreds); 
    RunInstancesRequest runInstancesRequest; 
    RunInstancesResult runInstancesResult; 
    Reservation reservation; 
    Instance intstance; 
    DescribeInstancesRequest describeInstanceRequest; 
    DescribeInstancesResult describeInstanceResult; 
    GatekeeperModal gateKeepermodal; 
    String sourceAMI = null; 
    String destinationAMI = null; 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     HttpSession s = request.getSession(); 
     String userID = (String) request.getParameter("userID"); 
     Double lattitude = Double.parseDouble((String) request.getParameter("lat")); 
     Double lonitude = Double.parseDouble((String) request.getParameter("long")); 
     if (userID != null) { 
      Pair coordinates = new Pair(lattitude, lonitude); 
      RegionSelection targetRegion = new RegionSelection(); 
      String regionResult = targetRegion.getRegion(coordinates); 
      String instanceIP = null; 
      gateKeepermodal = new GatekeeperModal(); 
      try { 
       if (gateKeepermodal.checkUserIsNew(userID)) { 
        instanceIP = startInstance(userID, regionResult); 
        if (instanceIP != null) { 
         response.getWriter().write(instanceIP); 
        } 
       } 
      } catch (SQLException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } else { 

     } 
    } 

    private String startInstance(String userID, String region) { 
     String ami_id = new AMI().getAMI_ID(region); 

     ec2Client.setEndpoint(region); 
     runInstancesRequest = new RunInstancesRequest(); 
     runInstancesRequest.withImageId(ami_id).withInstanceType("t2.micro").withMinCount(1).withMaxCount(1) 
       .withKeyName("GateKeeper_User").withSecurityGroups("GateKeeper User"); 
     runInstancesResult = ec2Client.runInstances(runInstancesRequest); 
     reservation = runInstancesResult.getReservation(); 
     intstance = reservation.getInstances().get(0); 
     String s1 = intstance.getState().getName(); 
     String s2 = InstanceStateName.Running.name(); 
     while (!s1.toLowerCase().equals(s2.toLowerCase())) { 
      describeInstanceRequest = new DescribeInstancesRequest(); 
      describeInstanceRequest.withInstanceIds(intstance.getInstanceId()); 
      ec2Client.setEndpoint(region); 
      describeInstanceResult = ec2Client.describeInstances(describeInstanceRequest); 
      reservation = describeInstanceResult.getReservations().get(0); 
      intstance = reservation.getInstances().get(0); 
      s1 = intstance.getState().getName(); 
      s2 = InstanceStateName.Running.name(); 
     } 
     GateKeeperUser user = new GateKeeperUser(userID, intstance.getInstanceId(), intstance.getPublicIpAddress(), 
       region); 
     Boolean result; 
     try { 
      result = gateKeepermodal.createUser(user); 
      if (result) { 
       return intstance.getPublicIpAddress(); 
      } else { 
       return null; 
      } 

     } catch (SQLException e) { 

     } 
     return null; 
    } 
} 

回答

2

按照documentation

「如果成功運行RunInstances命令,然後 使用在RunInstances的響應提供 實例ID立即運行另一個命令,它可能返回一個 InvalidInstanceID.NotFound錯誤,這並不意味着這個實例不存在 。一些可能受到影響的特定命令是: DescribeInstances:要確認實例的實際狀態,請運行 此命令使用指數退避算法。 TerminateInstances:要確認實例的狀態,請首先使用指數退避算法運行 DescribeInstances命令。「