O AWS SDK for Java 1.x entrou no modo de manutenção em 31 de julho de 2024 e chegará end-of-support
As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Tutorial: gerenciamento de requisições spot do Amazon EC2 avançado
Instâncias spot do Amazon EC2 permitem que você ofereça a capacidade não utilizada do Amazon EC2 e execute essas instâncias desde que a oferta ultrapasse o preço spot atual. O Amazon EC2 altera o preço spot periodicamente com base na oferta e na demanda. Para obter mais informações sobre instâncias spot, consulte Instâncias spot no Guia do usuário do Amazon EC2 para instâncias do Linux.
Pré-requisitos
Para usar este tutorial, você deve ter o AWS SDK for Java instalado, bem como ter atendido aos pré-requisitos de instalação básicos. Consulte Configurar o AWS SDK for Java para obter mais informações.
Configurar as credenciais
Para começar a usar esse exemplo de código, é preciso configurar credenciais da AWS. Consulte Configurar credenciais e a região da AWS para desenvolvimento para obter instruções sobre como fazer isso.
nota
Recomendamos usar as credenciais de um usuário do IAM para fornecer esses valores. Para obter mais informações, consulte Cadastrar-se na AWS e criar um usuário do IAM.
Agora que definiu as configurações, você pode começar a usar o código no exemplo.
Configurar um security group
Um security group funciona como um firewall que controla o tráfego permitido de entrada e saída de um grupo de instâncias. Por padrão, uma instância é iniciada sem nenhum security group, o que significa que todo o tráfego IP recebido, em qualquer porta TCP, será negado. Por isso, antes de enviar a requisição spot, vamos configurar um security group que permite o tráfego de rede necessário. Para os fins deste tutorial, criaremos um novo security group chamado "GettingStarted" que permite o tráfego Secure Shell (SSH) do endereço IP em que está executando o aplicativo. Para configurar um novo security group, você precisa incluir ou executar o exemplo de código a seguir que configura o security group de maneira programática.
Depois que criarmos um objeto de cliente AmazonEC2
, criaremos um objeto CreateSecurityGroupRequest
com o nome, "GettingStarted", e uma descrição do security group. Em seguida, chamaremos a API ec2.createSecurityGroup
para criar o grupo.
Para permitir acesso ao grupo, criaremos um objeto ipPermission
com o intervalo de endereços IP definido como a representação CIDR da sub-rede para o computador local; o sufixo "/10" no endereço IP indica a sub-rede do endereço IP especificado. Também configuramos o objeto ipPermission
com o protocolo TCP e a porta 22 (SSH). A etapa final é chamar ec2
.authorizeSecurityGroupIngress
com o nome do security group e o objeto ipPermission
.
(O código a seguir é o mesmo que usamos no primeiro tutorial.)
// Create the AmazonEC2Client object so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.standard() .withCredentials(credentials) .build(); // Create a new security group. try { CreateSecurityGroupRequest securityGroupRequest = new CreateSecurityGroupRequest("GettingStartedGroup", "Getting Started Security Group"); ec2.createSecurityGroup(securityGroupRequest); } catch (AmazonServiceException ase) { // Likely this means that the group is already created, so ignore. System.out.println(ase.getMessage()); } String ipAddr = "0.0.0.0/0"; // Get the IP of the current host, so that we can limit the Security Group // by default to the ip range associated with your subnet. try { // Get IP Address InetAddress addr = InetAddress.getLocalHost(); ipAddr = addr.getHostAddress()+"/10"; } catch (UnknownHostException e) { // Fail here... } // Create a range that you would like to populate. ArrayList<String> ipRanges = new ArrayList<String>(); ipRanges.add(ipAddr); // Open up port 22 for TCP traffic to the associated IP from // above (e.g. ssh traffic). ArrayList<IpPermission> ipPermissions = new ArrayList<IpPermission> (); IpPermission ipPermission = new IpPermission(); ipPermission.setIpProtocol("tcp"); ipPermission.setFromPort(new Integer(22)); ipPermission.setToPort(new Integer(22)); ipPermission.setIpRanges(ipRanges); ipPermissions.add(ipPermission); try { // Authorize the ports to the used. AuthorizeSecurityGroupIngressRequest ingressRequest = new AuthorizeSecurityGroupIngressRequest( "GettingStartedGroup",ipPermissions); ec2.authorizeSecurityGroupIngress(ingressRequest); } catch (AmazonServiceException ase) { // Ignore because this likely means the zone has already // been authorized. System.out.println(ase.getMessage()); }
Você pode visualizar todo esse exemplo de código em advanced.CreateSecurityGroupApp.java
. Você precisa somente executar esse aplicativo uma vez para criar um novo security group.
nota
Você também pode criar o security group usando o AWS Toolkit for Eclipse. Consulte Gerenciar grupos de segurança do AWS Cost Explorer no Guia do usuário do AWS Toolkit for Eclipse para obter mais informações.
Opções de criação da requisição da instância spot detalhadas
Como explicamos no Tutorial: instâncias spot do Amazon EC2, você precisa compilar a requisição com um tipo de instância, uma Imagem de máquina da Amazon (AMI) e um preço de sugestão de preço máximo.
Vamos começar criando um objeto RequestSpotInstanceRequest
. O objeto de requisição exige o número de instâncias que você deseja e o preço da sugestão. Além disso, precisamos definir o LaunchSpecification
da requisição, que inclui o tipo de instância, o ID de AMI e o security group que você deseja usar. Depois que a requisição for preenchida, chamaremos o método requestSpotInstances
no objeto AmazonEC2Client
. Veja a seguir um exemplo de como solicitar uma instância spot.
(O código a seguir é o mesmo que usamos no primeiro tutorial.)
// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set up the specifications of the launch. This includes the // instance type (e.g. t1.micro) and the latest Amazon Linux // AMI id available. Note, you should always use the latest // Amazon Linux AMI id or another of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
Requisições persistentes x ocasionais
Ao compilar uma requisição spot, você pode especificar diversos parâmetros opcionais. O primeiro é se a requisição é somente ocasional ou persistente. Por padrão, trata-se de uma requisição ocasional. A requisição ocasional pode ser atendida somente uma vez e, depois que as instâncias solicitadas forem encerradas, a requisição será fechada. Uma requisição persistente é considerada para o cumprimento sempre que não há instância spot em execução para a mesma requisição. Para especificar o tipo de requisição, basta definir o tipo na requisição spot. Isso pode ser feito com o código a seguir.
// Retrieves the credentials from an AWSCredentials.properties file. AWSCredentials credentials = null; try { credentials = new PropertiesCredentials( GettingStartedApp.class.getResourceAsStream("AwsCredentials.properties")); } catch (IOException e1) { System.out.println( "Credentials were not properly entered into AwsCredentials.properties."); System.out.println(e1.getMessage()); System.exit(-1); } // Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set the type of the bid to persistent. requestRequest.setType("persistent"); // Set up the specifications of the launch. This includes the // instance type (e.g. t1.micro) and the latest Amazon Linux // AMI id available. Note, you should always use the latest // Amazon Linux AMI id or another of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
Limitar a duração de uma requisição
Você também pode especificar o tempo em que a requisição permanecerá válida. Você pode especificar horários de início e término para esse período. Por padrão, uma requisição spot será considerada para o cumprimento a partir do momento em que é criada até ser atendida ou cancelada por você. No entanto, você poderá restringir o período de validade, se precisar. Um exemplo de como especificar esse período é mostrado no código a seguir.
// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set the valid start time to be two minutes from now. Calendar cal = Calendar.getInstance(); cal.add(Calendar.MINUTE, 2); requestRequest.setValidFrom(cal.getTime()); // Set the valid end time to be two minutes and two hours from now. cal.add(Calendar.HOUR, 2); requestRequest.setValidUntil(cal.getTime()); // Set up the specifications of the launch. This includes // the instance type (e.g. t1.micro) // and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon // Linux AMI id or another of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType("t1.micro"); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
Agrupar as requisições de instância spot do Amazon EC2
Você tem a opção de agrupar as requisições de instância spot de diversas maneiras diferentes. Veremos os benefícios de usar grupos de inicialização, grupos de zonas de disponibilidade e grupos de colocações.
Se quiser garantir que as instâncias spot sejam todas executadas e encerradas juntas, você terá a opção de aproveitar um grupo de inicialização. Grupo de inicialização é um rótulo que agrupa um conjunto de sugestões de preço. Todas as instâncias em um grupo de execução são iniciadas e encerradas juntas. Se instâncias em um grupo de inicialização já tiverem sido atendidas, não haverá garantia de que novas instâncias executadas com o mesmo grupo de inicialização também serão atendidas. Um exemplo de como definir um grupo de inicialização é mostrado no exemplo de código a seguir.
// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 5 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(5)); // Set the launch group. requestRequest.setLaunchGroup("ADVANCED-DEMO-LAUNCH-GROUP"); // Set up the specifications of the launch. This includes // the instance type (e.g. t1.micro) and the latest Amazon Linux // AMI id available. Note, you should always use the latest // Amazon Linux AMI id or another of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
Se quiser garantir que todas as instâncias dentro de uma solicitação sejam iniciadas na mesma zona de disponibilidade e não se preocupar com qual delas, será possível aproveitar os grupos de zonas de disponibilidade. Grupo de zonas de disponibilidade é um rótulo que agrupa um conjunto de instâncias na mesma zona de disponibilidade. Todas as instâncias que compartilham um grupo de zonas de disponibilidade e são atendidas simultaneamente começarão na mesma zona de disponibilidade. Um exemplo de como definir um grupo de zonas de disponibilidade está a seguir.
// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 5 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(5)); // Set the availability zone group. requestRequest.setAvailabilityZoneGroup("ADVANCED-DEMO-AZ-GROUP"); // Set up the specifications of the launch. This includes the instance // type (e.g. t1.micro) and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon Linux AMI id or another // of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
Você pode especificar uma zona de disponibilidade desejada para as instâncias spot. O código de exemplo a seguir mostra como definir uma zona de disponibilidade.
// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set up the specifications of the launch. This includes the instance // type (e.g. t1.micro) and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon Linux AMI id or another // of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Set up the availability zone to use. Note we could retrieve the // availability zones using the ec2.describeAvailabilityZones() API. For // this demo we will just use us-east-1a. SpotPlacement placement = new SpotPlacement("us-east-1b"); launchSpecification.setPlacement(placement); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
Por fim, será possível especificar um grupo de colocações se estiver usando instâncias spot High Performance Computing (HPC – Computação de Alto Desempenho), como instâncias de computação em cluster ou de GPU de cluster. Os grupos de colocações oferecem latência mais baixa e alta conectividade de largura de banda entre as instâncias. Um exemplo de como definir um grupo de colocações está a seguir.
// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set up the specifications of the launch. This includes the instance // type (e.g. t1.micro) and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon Linux AMI id or another // of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Set up the placement group to use with whatever name you desire. // For this demo we will just use "ADVANCED-DEMO-PLACEMENT-GROUP". SpotPlacement placement = new SpotPlacement(); placement.setGroupName("ADVANCED-DEMO-PLACEMENT-GROUP"); launchSpecification.setPlacement(placement); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
Todos os parâmetros mostrados nesta seção são opcionais. Também é importante perceber que a maioria desses parâmetros (com exceção da sugestão de preço ser ocasional ou persistente) pode reduzir a probabilidade de cumprimento da sugestão de preço. Por isso, será importante aproveitar essas opções somente se você precisar delas. Todos os exemplos de código anteriores são integrados a um exemplo longo, que pode ser encontrado na classe com.amazonaws.codesamples.advanced.InlineGettingStartedCodeSampleApp.java
.
Como manter uma partição raiz após a interrupção ou o encerramento
Uma das maneiras mais fáceis de gerenciar a interrupção das instâncias spot é garantir que os dados sejam verificados em um volume do Amazon Elastic Block Store (Amazon Amazon EBS) em um ritmo regular. Verificando periodicamente, se houver uma interrupção, você perderá somente os dados criados desde o ponto de verificação mais recente (pressupondo-se que não haja outras ações não idempotentes realizadas entre essas duas situações). Para facilitar ainda mais esse processo, você pode configurar a requisição spot para garantir que a partição raiz não seja excluída na interrupção ou no encerramento. Inserimos um novo código no exemplo a seguir que mostra como habilitar esse cenário.
No código adicionado, criamos um objeto BlockDeviceMapping
e definimos o Amazon Elastic Block Store (Amazon EBS) associado como um objeto Amazon EBS que configuramos como not
caso a instância spot seja encerrada. Em seguida, adicionaremos o BlockDeviceMapping
a ArrayList de mapeamentos que incluímos na especificação de inicialização.
// Retrieves the credentials from an AWSCredentials.properties file. AWSCredentials credentials = null; try { credentials = new PropertiesCredentials( GettingStartedApp.class.getResourceAsStream("AwsCredentials.properties")); } catch (IOException e1) { System.out.println( "Credentials were not properly entered into AwsCredentials.properties."); System.out.println(e1.getMessage()); System.exit(-1); } // Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set up the specifications of the launch. This includes the instance // type (e.g. t1.micro) and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon Linux AMI id or another // of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Create the block device mapping to describe the root partition. BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping(); blockDeviceMapping.setDeviceName("/dev/sda1"); // Set the delete on termination flag to false. EbsBlockDevice ebs = new EbsBlockDevice(); ebs.setDeleteOnTermination(Boolean.FALSE); blockDeviceMapping.setEbs(ebs); // Add the block device mapping to the block list. ArrayList<BlockDeviceMapping> blockList = new ArrayList<BlockDeviceMapping>(); blockList.add(blockDeviceMapping); // Set the block device mapping configuration in the launch specifications. launchSpecification.setBlockDeviceMappings(blockList); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
Pressupondo-se que queira reanexar esse volume à instância na inicialização, você também pode usar as configurações de mapeamento de dispositivos de blocos. Como alternativa, se você tiver anexado uma partição não raiz, será possível especificar os volumes do Amazon Amazon EBS que queira anexar à instância spot após o reinício. Você pode fazer isso simplesmente especificando um ID de snapshot no EbsBlockDevice
e um nome de dispositivo alternativo nos objetos BlockDeviceMapping
. Utilizando-se mapeamentos de dispositivos de blocos, pode ser mais fácil inicializar a instância.
Usar a partição raiz no ponto de verificação dos dados críticos é uma ótima maneira de gerenciar o potencial de interrupção das instâncias. Para obter mais métodos para gerenciar o potencial de interrupção, assista ao vídeo Gerenciar interrupções
Como marcar as requisições spot e as instâncias
Adicionar tags a recursos do Amazon EC2 pode simplificar a administração da infraestrutura em nuvem. Uma forma de metadados, as tags podem ser usadas para criar nomes amigáveis ao usuário, aprimorar a capacidade de pesquisa e melhorar a coordenação entre vários usuários. Você também pode usar tags para automatizar scripts e partes dos processos. Para ler mais sobre como marcar recursos do Amazon EC2, acesse Usar tags no Guia do usuário do Amazon EC2 para instâncias do Linux.
Marcar requisições
Para adicionar tags às requisições spot, você precisará marcá-las depois que tiverem sido solicitadas. O valor de retorno de requestSpotInstances()
fornece um objeto RequestSpotInstancesResult que você pode usar para obter os IDs de requisição spot para marcar:
// Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest); List<SpotInstanceRequest> requestResponses = requestResult.getSpotInstanceRequests(); // A list of request IDs to tag ArrayList<String> spotInstanceRequestIds = new ArrayList<String>(); // Add the request ids to the hashset, so we can determine when they hit the // active state. for (SpotInstanceRequest requestResponse : requestResponses) { System.out.println("Created Spot Request: "+requestResponse.getSpotInstanceRequestId()); spotInstanceRequestIds.add(requestResponse.getSpotInstanceRequestId()); }
Assim que você tiver os IDs, será possível marcar as solicitações adicionando os IDs a um CreateTagsRequest e chamando o método createTags()
do cliente do Amazon EC2:
// The list of tags to create ArrayList<Tag> requestTags = new ArrayList<Tag>(); requestTags.add(new Tag("keyname1","value1")); // Create the tag request CreateTagsRequest createTagsRequest_requests = new CreateTagsRequest(); createTagsRequest_requests.setResources(spotInstanceRequestIds); createTagsRequest_requests.setTags(requestTags); // Tag the spot request try { ec2.createTags(createTagsRequest_requests); } catch (AmazonServiceException e) { System.out.println("Error terminating instances"); System.out.println("Caught Exception: " + e.getMessage()); System.out.println("Reponse Status Code: " + e.getStatusCode()); System.out.println("Error Code: " + e.getErrorCode()); System.out.println("Request ID: " + e.getRequestId()); }
Marcar instâncias
De maneira semelhante a requisições spot, você poderá marcar somente uma instância depois que ela tiver sido criada, o que acontecerá assim que a requisição spot tiver sido atendida (deixa de estar no estado aberto).
É possível verificar o status das solicitações chamando o método describeSpotInstanceRequests()
do cliente do Amazon EC2 com um objeto DescribeSpotInstanceRequestsRequest. O objeto DescribeSpotInstanceRequestsResult retornado contém uma lista de objetos SpotInstanceRequest que você pode usar para consultar o status das requisições spot e obter os IDs de instância assim que elas não estiverem mais no estado aberto.
Assim que a requisição spot não estiver mais aberta, você poderá recuperar o ID de instância do objeto SpotInstanceRequest
chamando o método getInstanceId()
.
boolean anyOpen; // tracks whether any requests are still open // a list of instances to tag. ArrayList<String> instanceIds = new ArrayList<String>(); do { DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest(); describeRequest.setSpotInstanceRequestIds(spotInstanceRequestIds); anyOpen=false; // assume no requests are still open try { // Get the requests to monitor DescribeSpotInstanceRequestsResult describeResult = ec2.describeSpotInstanceRequests(describeRequest); List<SpotInstanceRequest> describeResponses = describeResult.getSpotInstanceRequests(); // are any requests open? for (SpotInstanceRequest describeResponse : describeResponses) { if (describeResponse.getState().equals("open")) { anyOpen = true; break; } // get the corresponding instance ID of the spot request instanceIds.add(describeResponse.getInstanceId()); } } catch (AmazonServiceException e) { // Don't break the loop due to an exception (it may be a temporary issue) anyOpen = true; } try { Thread.sleep(60*1000); // sleep 60s. } catch (Exception e) { // Do nothing if the thread woke up early. } } while (anyOpen);
Você já pode marcar as instâncias retornadas:
// Create a list of tags to create ArrayList<Tag> instanceTags = new ArrayList<Tag>(); instanceTags.add(new Tag("keyname1","value1")); // Create the tag request CreateTagsRequest createTagsRequest_instances = new CreateTagsRequest(); createTagsRequest_instances.setResources(instanceIds); createTagsRequest_instances.setTags(instanceTags); // Tag the instance try { ec2.createTags(createTagsRequest_instances); } catch (AmazonServiceException e) { // Write out any exceptions that may have occurred. System.out.println("Error terminating instances"); System.out.println("Caught Exception: " + e.getMessage()); System.out.println("Reponse Status Code: " + e.getStatusCode()); System.out.println("Error Code: " + e.getErrorCode()); System.out.println("Request ID: " + e.getRequestId()); }
Cancelar requisições spot e encerrar instâncias
Cancelar uma requisição spot
Para cancelar uma requisição de instância spot, chame cancelSpotInstanceRequests
no cliente do Amazon EC2 com um objeto CancelSpotInstanceRequestsRequest.
try { CancelSpotInstanceRequestsRequest cancelRequest = new CancelSpotInstanceRequestsRequest(spotInstanceRequestIds); ec2.cancelSpotInstanceRequests(cancelRequest); } catch (AmazonServiceException e) { System.out.println("Error cancelling instances"); System.out.println("Caught Exception: " + e.getMessage()); System.out.println("Reponse Status Code: " + e.getStatusCode()); System.out.println("Error Code: " + e.getErrorCode()); System.out.println("Request ID: " + e.getRequestId()); }
Encerrar instâncias spot
É possível encerrar todas as instâncias spot em execução passando os IDs para o método terminateInstances()
do cliente do Amazon EC2.
try { TerminateInstancesRequest terminateRequest = new TerminateInstancesRequest(instanceIds); ec2.terminateInstances(terminateRequest); } catch (AmazonServiceException e) { System.out.println("Error terminating instances"); System.out.println("Caught Exception: " + e.getMessage()); System.out.println("Reponse Status Code: " + e.getStatusCode()); System.out.println("Error Code: " + e.getErrorCode()); System.out.println("Request ID: " + e.getRequestId()); }
Resumir
Para resumir, fornecemos uma abordagem mais orientada a objeto que integra as etapas que mostramos neste tutorial em uma única classe fácil de usar. Instanciamos uma classe chamada Requests
que realiza essas ações. Também criamos uma classe GettingStartedApp
, que tem um método principal em que realizamos as chamadas à função de alto nível.
O código-fonte completo desse exemplo pode ser visualizado ou obtido por download no GitHub
Parabéns! Você concluiu o tutorial Recursos de solicitação avançados para desenvolver o software de instância spot com o AWS SDK for Java.