2016-08-17 297 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命令。“