CodeSample小助手 2021-09-06
您在使用抢占式实例时,实例会因为库存或价格的波动而中断实例,中断后数据无法恢复。我们可以采用感知抢占式实例中断事件自动创建镜像,然后使用创建出的镜像来创建实例,防止实例中断而导致的数据丢失。
工作流程如下图所示。
在使用本教程之前,请确保已完成以下操作:
请在阿里云控制台中的AccessKey管理页面查看您的访问密钥。您只有获取了阿里云账号和访问密钥(AccessKey),才可以使用Alibaba Cloud SDK for Java。
确保您已经安装了Alibaba Cloud SDK for Java,准确的SDK版本号,请参见阿里云开发工具包(SDK)。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>java.demo</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-ecs</artifactId>
<version>4.23.10</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.8</version>
</dependency>
</dependencies>
</project>
本文操作示例主要以代码形式体现,具体代码如下:
创建抢占式实例。
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.RunInstancesRequest;
import com.aliyuncs.ecs.model.v20140526.RunInstancesResponse;
import com.aliyuncs.profile.DefaultProfile;
/**
* 通过RunInstances创建抢占式实例。
*/
public class CreateSpotInstance {
static IAcsClient client;
/**
* 请将regionId修改为您实例的地域ID。
*/
static String regionId = "cn-shanghai";
/**
* 请将zoneId修改为您实例的可用区ID。
*/
static String zoneId = "cn-shanghai-l";
/**
* 请将InstanceType修改为您需要的实例规格。
*/
static String instanceType = "ecs.s6-c1m1.small";
/**
* 请将imagesId修改为您需要的镜像ID。
*/
static String imagesId = "centos_7_06_64_20G_alibase_20190711.vhd";
/**
* 请将vSwitchId修改为您的交换机ID。
*/
static String vSwitchId = "<your-vsw-id>";
/**
* 请将securityGroupId修改为您的安全组ID。
*/
static String securityGroupId = "<your-sg-id>";
/**
* 请将spotStrategy修改为您想选择的抢占策略。
*/
static String spotStrategy = "SpotAsPriceGo";
/**
* 请将spotDuration修改为您想使用的时长,如果您不确定时长,可以设置为0。
*/
static Integer spotDuration = 0;
/**
* 请将password修改为您的密码。
*/
static String password = "<your-passwd>";
public static void main(String[] args) {
client = Initialization();
createInstance();
}
private static IAcsClient Initialization() {
// 初始化请求参数。
DefaultProfile profile = DefaultProfile.getProfile(
regionId, // 您的实例所在地域ID。
"<your-access-key-id>", // 您的AccessKey ID。
"<your-access-key-secret>"); // 您的AccessKey Secret。
return new DefaultAcsClient(profile);
}
//创建实例。
public static String createInstance() {
try {
RunInstancesRequest request = new RunInstancesRequest();
request.setRegionId(regionId);
request.setZoneId(zoneId);
request.setInstanceType(instanceType);
request.setSpotDuration(spotDuration);
request.setSpotStrategy(spotStrategy);
request.setImageId(imagesId);
request.setVSwitchId(vSwitchId);
request.setSecurityGroupId(securityGroupId);
request.setInstanceChargeType("PostPaid");
request.setPassword(password);
request.setInternetMaxBandwidthOut(1);
RunInstancesResponse response = client.getAcsResponse(request);
if (null == response.getInstanceIdSets() || response.getInstanceIdSets().isEmpty()) {
return null;
}
String instanceId = response.getInstanceIdSets().get(0);
System.out.println("创建的实例ID: " + instanceId);
return instanceId;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
感知SPOT实例中断事件, 并自动创建自定义镜像。
import com.alibaba.fastjson.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.*;
import com.aliyuncs.profile.DefaultProfile;
import java.util.ArrayList;
import java.util.List;
/**
*感知SPOT实例中断事件, 并自动创建自定义镜像。
*
*通过DescribeInstances查询实例信息。
*
*通过CreateImage 创建自定义镜像。
*/
public class CreateSpotImage {
static IAcsClient client;
/**
* 请将regionNo修改为您实例的地域ID。
*/
static String regionId = "cn-shanghai";
/**
* 请将instanceId修改为您的实例ID。
*/
static String instanceId = "<your-instance-id>";
public static void main(String[] args) {
client = Initialization();
// 1. 等待实例到待回收状态。
waitForInstanceMarked();
System.out.println("spot instance will be recycled immediately, instance id:" + instanceId);
// 2. 实例被标记为待回收之后,创建镜像,以便后续恢复。
String image1 = createImage();
waitCreateImageSuccess(image1);
}
public static void waitForInstanceMarked() {
ArrayList<String> instanceIds = new ArrayList<>();
instanceIds.add(instanceId);
String instanceIdStr = JSON.toJSONString(instanceIds);
boolean isMarked = false;
// 判断实例是否被标记为待回收。
while (!isMarked) {
try {
DescribeInstancesRequest request = new DescribeInstancesRequest();
// 指定实例所在的地域。
request.setRegionId(regionId);
// 指定实例ID,提高查询效率。
request.setInstanceIds(instanceIdStr);
// 接收响应结果。
DescribeInstancesResponse response = client.getAcsResponse(request);
// 获取实例相关的返回结果。
List<DescribeInstancesResponse.Instance> instanceList = response.getInstances();
if (instanceList == null || instanceList.isEmpty()) {
break;
}
DescribeInstancesResponse.Instance instance = instanceList.get(0);
// 输出被查询的实例ID与可用区信息。
if (instance.getOperationLocks() == null) {
continue;
}
for (DescribeInstancesResponse.Instance.LockReason lockReason : instance.getOperationLocks()) {
// 如果实例被锁定,输出指定实例ID以及对应的锁定类型。
System.out.println("instance:" + instance.getInstanceId() + "-->lockReason:" + lockReason.getLockReason() + ",vmStatus:" + instance.getStatus());
if ("Recycling".equals(lockReason.getLockReason())) {
isMarked = true;
}
}
Thread.sleep(2 * 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static String createImage() {
try {
CreateImageRequest request = new CreateImageRequest();
request.setRegionId(regionId);
request.setInstanceId(instanceId);
CreateImageResponse response = client.getAcsResponse(request);
System.out.println(response.getImageId());
return response.getImageId();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void waitCreateImageSuccess(String imageId) {
boolean isSuccess = false;
while (!isSuccess) {
DescribeImagesResponse.Image image = describeImage(imageId);
if (null == image) {
System.err.println("image not exist. imageId: " + imageId);
break;
}
if ("Available".equals(image.getStatus())) {
isSuccess = true;
}
}
}
public static DescribeImagesResponse.Image describeImage(String imageId) {
try {
Thread.sleep(6 * 60 * 1000 );
DescribeImagesRequest imagesRequest = new DescribeImagesRequest();
imagesRequest.setRegionId(regionId);
imagesRequest.setImageId(imageId);
imagesRequest.setPageSize(100);
DescribeImagesResponse imagesResponse = client.getAcsResponse(imagesRequest);
if (null == imagesResponse.getImages() || imagesResponse.getImages().isEmpty()) {
return null;
}
return imagesResponse.getImages().get(0);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static IAcsClient Initialization() {
// 初始化请求参数。
DefaultProfile profile = DefaultProfile.getProfile(
regionId, // 您的实例所在地域ID。
"<your-access-key-id>", // 您的AccessKey ID。
"<your-access-key-secret>"); // 您的AccessKey Secret。
return new DefaultAcsClient(profile);
}
}
创建使用自定义镜像的抢占式实例,将imageId替换成第二步中创建的imageId。
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.RunInstancesRequest;
import com.aliyuncs.ecs.model.v20140526.RunInstancesResponse;
import com.aliyuncs.profile.DefaultProfile;
/**
*通过RunInstances创建抢占式实例。
*/
public class CreateSpotInstanceFromImage {
static IAcsClient client;
/**
* 请将regionNo修改为您实例的地域ID。
*/
static String regionId = "cn-shanghai";
/**
* 请将zoneId修改为您实例的可用区ID。
*/
static String zoneId = "cn-shanghai-l";
/**
* 请将InstanceType修改为您需要的实例规格。
*/
static String instanceType = "ecs.s6-c1m1.small";
/**
* 将此imageId改成上一步自定义生成的imageId。
*/
static String imagesId = "<your-image-id>";
/**
* 请将vSwitchId修改为您的交换机ID。
*/
static String vSwitchId = "<your-vsw-id>";
/**
* 请将securityGroupId修改为您的安全组ID。
*/
static String securityGroupId = "<your-sg-id>";
/**
* 请将spotStrategy修改为您想选择的抢占策略。
*/
static String spotStrategy = "SpotAsPriceGo";
/**
* 请将spotDuration修改为您想使用的时长,如果您不确定时长,可以设置为0。
*/
static Integer spotDuration = 0;
/**
* 请将password修改为您的密码。
*/
static String password = "<your-passwd>";
public static void main(String[] args) {
client = Initialization();
createInstance();
}
private static IAcsClient Initialization() {
// 初始化请求参数。
DefaultProfile profile = DefaultProfile.getProfile(
regionId, // 您的实例所在地域ID。
"<your-access-key-id>", // 您的AccessKey ID。
"<your-access-key-secret>"); // 您的AccessKey Secret。
return new DefaultAcsClient(profile);
}
//创建实例。
public static String createInstance() {
try {
RunInstancesRequest request = new RunInstancesRequest();
request.setRegionId(regionId);
request.setZoneId(zoneId);
request.setInstanceType(instanceType);
request.setSpotDuration(spotDuration);
request.setSpotStrategy(spotStrategy);
request.setImageId(imagesId);
request.setVSwitchId(vSwitchId);
request.setSecurityGroupId(securityGroupId);
request.setInstanceChargeType("PostPaid");
request.setPassword(password);
request.setInternetMaxBandwidthOut(1);
RunInstancesResponse response = client.getAcsResponse(request);
if (null == response.getInstanceIdSets() || response.getInstanceIdSets().isEmpty()) {
return null;
}
String instanceId = response.getInstanceIdSets().get(0);
System.out.println("创建的实例ID: " + instanceId);
return instanceId;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}