教學課程:進階 Amazon EC2 Spot 請求管理 - AWS SDK for Java 1.x

AWS SDK for Java 1.x 已於 2025 年 12 月 31 日end-of-support。我們建議您遷移至 AWS SDK for Java 2.x,以繼續接收新功能、可用性改善和安全性更新。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

教學課程:進階 Amazon EC2 Spot 請求管理

Amazon EC2 Spot 執行個體可讓您競價未使用的 Amazon EC2 容量,並在競價超過目前 Spot 價格時執行這些執行個體。 會根據供需定期 Amazon EC2 變更 Spot 價格。如需 Spot 執行個體的詳細資訊,請參閱《Linux 執行個體使用者指南》中的 Spot 執行個體。 Amazon EC2

先決條件

若要使用此教學課程,您必須 AWS SDK for Java 安裝 ,並符合其基本安裝先決條件。如需詳細資訊,請參閱設定 AWS SDK for Java

設定您的登入資料

若要開始使用此程式碼範例,您需要設定 AWS 登入資料。如需如何執行此作業的說明,請參閱設定開發的 AWS 登入資料和區域

注意

我們建議您使用 IAM 使用者的登入資料來提供這些值。如需詳細資訊,請參閱註冊 AWS 和建立 IAM 使用者

現在您已設定好設定,您可以開始使用範例中的程式碼。

設定安全群組

安全群組可做為防火牆,控制允許進出一組執行個體的流量。根據預設,執行個體會在沒有任何安全群組的情況下啟動,這表示在任何 TCP 連接埠上的所有傳入 IP 流量都會遭到拒絕。因此,在提交 Spot 請求之前,我們會設定允許必要網路流量的安全群組。基於本教學的目的,我們將建立新的安全群組,名為「GettingStarted」,允許來自您執行應用程式的 IP 地址的安全殼層 (SSH) 流量。若要設定新的安全群組,您需要包含或執行下列程式碼範例,以程式設計方式設定安全群組。

建立AmazonEC2用戶端物件之後,我們會建立名稱為「GettingStarted」的CreateSecurityGroupRequest物件,以及安全群組的描述。然後,我們呼叫 ec2.createSecurityGroup API 來建立 群組。

為了啟用群組的存取,我們會建立 IP 地址範圍設為本機電腦子網路 CIDR 表示法的ipPermission物件;IP 地址上的 "/10" 尾碼表示指定 IP 地址的子網路。我們也使用 TCP 通訊協定和連接埠 22 (SSH) 設定ipPermission物件。最後一個步驟是ec2 .authorizeSecurityGroupIngress使用安全群組的名稱和 ipPermission 物件呼叫 。

(下列程式碼與我們在第一個教學課程中所使用的程式碼相同。)

// 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()); }

您可以在程式碼範例中檢視整個advanced.CreateSecurityGroupApp.java程式碼範例。請注意,您只需要執行此應用程式一次,即可建立新的安全群組。

注意

您也可以使用 建立安全群組 AWS Toolkit for Eclipse。如需詳細資訊,請參閱 AWS Toolkit for Eclipse 《 使用者指南》中的從 管理安全群組 AWS Cost Explorer

詳細的 Spot 執行個體請求建立選項

我們在教學課程: Amazon EC2 Spot 執行個體中所說明,您需要使用執行個體類型、Amazon Machine Image (AMI) 和最高出價來建置請求。

讓我們從建立RequestSpotInstanceRequest物件開始。請求物件需要您想要的執行個體數量和出價。此外,我們需要LaunchSpecification為 請求設定 ,其中包括您想要使用的執行個體類型、AMI ID 和安全群組。填入請求後,我們會在 AmazonEC2Client 物件上呼叫 requestSpotInstances方法。以下範例說明如何請求 Spot 執行個體。

(下列程式碼與我們在第一個教學課程中所使用的程式碼相同。)

// 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);

持久性與一次性請求

建置 Spot 請求時,您可以指定數個選用參數。首先是您的請求是一次性還是持久性。根據預設,這是一次性請求。一次性請求只能履行一次,在請求的執行個體終止後,請求將會關閉。每當相同請求沒有執行的 Spot 執行個體時,就會考慮持續請求。若要指定請求類型,您只需在 Spot 請求上設定類型。這可以使用下列程式碼來完成。

// 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);

限制請求的持續時間

您也可以選擇性地指定請求將保持有效的時間長度。您可以指定此期間的開始和結束時間。根據預設,Spot 請求將從建立開始考慮履行,直到您履行或取消為止。不過,如有需要,您可以限制有效期間。以下程式碼顯示如何指定此期間的範例。

// 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);

分組 Spot Amazon EC2 執行個體請求

您可以選擇以數種不同的方式分組 Spot 執行個體請求。我們將探討使用啟動群組、可用區域群組和置放群組的優點。

如果您想要確保 Spot 執行個體一起啟動和終止,則可以選擇利用啟動群組。啟動群組是將一組出價分組在一起的標籤。啟動群組中的所有執行個體會同時啟動和終止。請注意,如果已滿足啟動群組中的執行個體,則無法保證也會滿足使用相同啟動群組啟動的新執行個體。下列程式碼範例顯示如何設定啟動群組的範例。

// 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);

如果您想要確保在相同可用區域中啟動請求中的所有執行個體,而且您不在乎哪個執行個體,您可以利用可用區域群組。可用區域群組是將一組執行個體分組在相同可用區域中的標籤。所有共用可用區域群組且同時履行的執行個體都會在相同的可用區域中開始。以下範例說明如何設定可用區域群組。

// 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);

您可以指定 Spot 執行個體所需的可用區域。下列程式碼範例示範如何設定可用區域。

// 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);

最後,如果您使用的是高效能運算 (HPC) Spot 執行個體,例如叢集運算執行個體或叢集 GPU 執行個體,您可以指定置放群組。置放群組可在執行個體之間提供較低的延遲和高頻寬連線。以下範例說明如何設定置放群組。

// 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);

本節顯示的所有參數都是選用的。也請務必了解,除了您的出價是一次性還是持久性之外,大多數這些參數都可能降低出價履行的可能性。因此,只有在您需要時才利用這些選項非常重要。上述所有程式碼範例都會合併為一個長程式碼範例,可在 com.amazonaws.codesamples.advanced.InlineGettingStartedCodeSampleApp.java類別中找到。

如何在中斷或終止後保留根分割區

管理 Spot 執行個體中斷最簡單的方式之一,就是確保您的資料定期檢查點至 Amazon Elastic Block Store (Amazon Amazon EBS) 磁碟區。透過定期檢查點,如果發生中斷,您只會遺失自上次檢查點之後建立的資料 (假設之間沒有執行其他非等冪動作)。若要讓此程序更簡單,您可以設定 Spot 請求,以確保根分割區不會在中斷或終止時遭到刪除。我們已在下列範例中插入新的程式碼,示範如何啟用此案例。

在新增的程式碼中,我們會建立BlockDeviceMapping物件,並將其 associated Amazon Elastic Block Store (Amazon EBS) 設定為在 Spot 執行個體終止時,已設定not刪除的 Amazon EBS 物件。然後BlockDeviceMapping,我們會將此新增至我們在啟動規格中包含的映射 ArrayList。

// 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);

假設您想要在啟動時將此磁碟區重新連接至執行個體,您也可以使用區塊型設備映射設定。或者,如果您連接了非根分割區,您可以在 Spot 執行個體恢復後指定要連接到 Spot 執行個體的 Amazon Amazon EBS 磁碟區。您只需在 中指定快照 ID,EbsBlockDevice並在 BlockDeviceMapping 物件中指定替代裝置名稱即可。透過利用區塊型設備映射,您可以更輕鬆地引導執行個體。

使用根分割區來檢查點您的關鍵資料,是管理執行個體中斷可能性的絕佳方式。如需管理中斷可能性的更多方法,請造訪管理中斷影片。

如何標記 Spot 請求和執行個體

將標籤新增至 Amazon EC2 資源可以簡化雲端基礎設施的管理。標籤是一種中繼資料形式,可用來建立易用的名稱、增強可搜尋性,並改善多個使用者之間的協調性。您也可以使用標籤來自動化指令碼和部分程序。若要進一步了解標記 Amazon EC2 資源,請前往《Linux 執行個體 Amazon EC2 使用者指南》中的使用標籤

標記 請求

若要將標籤新增至 Spot 請求,您需要在請求之後標記它們。的傳回值requestSpotInstances()為您提供 RequestSpotInstancesResult 物件,您可以用來取得標記的 Spot IDs:

// 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()); }

擁有 IDs後,您可以將請求IDs 新增至 CreateTagsRequest 並呼叫 Amazon EC2 用戶端的 createTags()方法,以標記請求:

// 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()); }

標記執行個體

與 spot 請求本身類似,您只能在執行個體建立後標記執行個體,這會在 Spot 請求滿足後發生 (不再處於開啟狀態)。

您可以使用 DescribeSpotInstanceRequestsRequest 物件呼叫 Amazon EC2 用戶端的 describeSpotInstanceRequests()方法,來檢查請求的狀態。傳回的 DescribeSpotInstanceRequestsResult 物件包含 SpotInstanceRequest 物件清單,您可以用來查詢 Spot 請求的狀態,並在執行個體不再處於開啟狀態時取得其執行個體 IDs。

一旦 Spot 請求不再開啟,您可以透過呼叫其getInstanceId()方法,從SpotInstanceRequest物件擷取其執行個體 ID。

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);

現在您可以標記傳回的執行個體:

// 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()); }

取消 Spot 請求和終止執行個體

取消 Spot 請求

若要取消 Spot 執行個體請求,請在 Amazon EC2 用戶端cancelSpotInstanceRequests上使用 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()); }

終止 Spot 執行個體

您可以透過將任何正在執行的 Spot 執行個體 IDs傳遞至 Amazon EC2 用戶端的 terminateInstances()方法來終止這些執行個體。

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()); }

全部整合

為了將這些整合在一起,我們提供更以物件為導向的方法,將我們在本教學課程中顯示的步驟合併為一個易於使用的類別。我們會執行個體化名為 的類別Requests,以執行這些動作。我們也建立一個GettingStartedApp類別,它具有主要方法,用於執行高階函數呼叫。

您可以在 GitHub 檢視或下載此範例的完整原始程式碼。

恭喜您!您已完成使用 開發 Spot 執行個體軟體的進階請求功能教學課程 AWS SDK for Java。