All Products
Search
Document Center

Elastic Compute Service:create a custom image from a system disk snapshot

Last Updated:Mar 29, 2024

Preemptible instances may be forcefully reclaimed due to price fluctuations or changes in market supply and demand. To prevent loss of data stored on a preemptible instance, you can configure the system to create a snapshot for the system disk of the instance and create a custom image from the snapshot. Then, you can create a preemptible instance from the custom image to restore the data stored on the source preemptible instance. This topic describes how to use Java code to detect interruption events of preemptible instances before the instances are reclaimed. When an interruption event of a preemptible instance is detected, the system creates a snapshot for the system disk of the instance and creates a custom image from the snapshot. Then, you can create a preemptible instance from the custom image to restore the data that is stored on the source preemptible instance. In this topic, Alibaba Cloud Elastic Compute Service (ECS) SDK for Java is used.

Working mechanism

When you use a preemptible instance, the instance may be forcefully reclaimed due to price fluctuations or changes in market supply and demand. Before the instance is fully reclaimed, it enters the Locked state and an interruption event is triggered for the instance.

You can set a monitoring mechanism based on the interruption event, and configure the system disk not to be released along with the instance when the instance is running as expected. After you receive an interruption event of the preemptible instance, you can use Java code to create a snapshot for the system disk and create a custom image from the system disk snapshot. Then, you can create a preemptible instance from the custom image. This way, you can restore the data that is stored on the source preemptible instance.

Note

You can configure the system disk not to be released along with the associated preemptible instance. If the preemptible instance is released, the system disk snapshot and the custom image are not affected.

The following figure shows the O&M workflow in this example.

image

Prerequisites

  • An Alibaba Cloud account is created and the AccessKey pair of the account is obtained.

    You must configure the AccessKey pair of your Alibaba Cloud account to use Alibaba Cloud ECS SDK for Java. For information about how to obtain the AccessKey pair, see Create an AccessKey pair.

  • ECS SDK for Java is installed in the development environment.

    You must add the following dependencies to the Maven project. For more information, see Install ECS SDK for Java.

    <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.83</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>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-collections4</artifactId>
                <version>4.4</version>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>20.0</version>
            </dependency>
        </dependencies>
    </project>

Precautions

Important

The following sample code is used for reference only. The custom image creation process and data restoration process may require more than 5 minutes to complete.

After an interruption event is triggered for a preemptible instance, notifications are sent at least 5 minutes before the instance is fully claimed. However, the amount of time required to restore data depends on the image type of the instance and the size of the system disk. The larger the size of the system disk, the longer it takes to restore data. Before you use the sample code, evaluate and verify the effect of data restoration.

Limits

The following limits apply when data of a preemptible instance is restored before the instance is reclaimed:

  • To ensure that disk snapshots are not lost, we recommend that you disable the Delete Automatic Snapshots While Releasing Disk feature.

  • If the data disks of a preemptible instance contain important data, we recommend that you configure the data disks not to be released along with the instance. For more information, see Use the ECS console in the Step 2: Configure the system disk not to be released along with the instance section of this topic.

  • If you call the ModifyDiskAttribute operation with the DeleteWithInstance parameter set to false for a disk and the instance to which the disk is attached is locked for security reasons, the DeleteWithInstance parameter is ignored and the disk will be released along with the instance. If OperationLocks in the DescribeInstances response contains "LockReason" : "security" for an instance, the instance is locked for security reasons.

    Note

    You can use the DiskIds.N parameter to modify the attributes of multiple Elastic Block Storage (EBS) devices at the same time, including the device names, device descriptions, and whether to release the devices along with the associated instances.

Step 1: Create a preemptible instance

In this step, the CreateSpotInstance Java class is used. The following sample code provides an example on how to create a preemptible instance by calling the RunInstances operation.

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;

/**
 * Call the RunInstances operation to create a preemptible instance. 
 */
public class CreateSpotInstance {

    static IAcsClient client;
    // Specify the ID of the region in which to create the preemptible instance.  
    static String regionId = "cn-hangzhou";
    // Specify the ID of the zone in which to create the preemptible instance.  
    static String zoneId = "cn-hangzhou-i";
    // Specify the instance type of the preemptible instance. 
    static String instanceType = "ecs.s6-c1m1.small";
    // Specify the ID of the image to use to create the preemptible instance. 
    static String imagesId = "centos_7_6_x64_20G_alibase_20211130.vhd";
    // Specify the ID of the vSwitch to which to connect the preemptible instance. 
    static String vSwitchId = "<your-vSwitchId>";
    // Specify the ID of the security group to which to assign the preemptible instance. 
    static String securityGroupId = "<your-securityGroupId>";
    // Specify a preemption policy. 
    static String spotStrategy = "SpotAsPriceGo";
    // Specify the protection period of the preemptible instance. If you cannot determine the protection period, set the value to 0. 
    static Integer spotDuration = 0;
    // Specify the logon password of the preemptible instance. 
    static String password = "<your-password>";

    public static void main(String[] args) {
        client = initialization();
        createInstance();
    }

    private static IAcsClient initialization() {
        /**
         * Initialize request parameters. 
         * Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are configured. 
         * If the project code is leaked, the AccessKey pair may be leaked and the security of all resources in your account may be compromised. The following sample code provides an example on how to use environment variables to obtain an AccessKey pair and then use the AccessKey pair to call API operations. We recommend that you use Security Token Service (STS) tokens, which provide higher security. 
         */
        DefaultProfile profile = DefaultProfile.getProfile(regionId, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        return new DefaultAcsClient(profile);
    }

    // Create a preemption instance. 
    public static String createInstance() {
        try {
            // Configure the parameters of the RunInstances operation and send the request. 
            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);
            // The preemption policy takes effect only when InstanceChargeType is set to PostPaid. 
            request.setInstanceChargeType("PostPaid");
            request.setPassword(password);
            request.setInternetMaxBandwidthOut(1);
            // Obtain the response and the instance ID. 
            RunInstancesResponse response = client.getAcsResponse(request);
            if (null == response.getInstanceIdSets() || response.getInstanceIdSets().isEmpty()) {
                return null;
            }
            String instanceId = response.getInstanceIdSets().get(0);
            System.out.println("Instance ID:" + instanceId);
            return instanceId;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

Step 2: Configure the system disk not to be released along with the instance

Use the Java code

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.DescribeDisksRequest;
import com.aliyuncs.ecs.model.v20140526.DescribeDisksResponse;
import com.aliyuncs.ecs.model.v20140526.DescribeDisksResponse.Disk;
import com.aliyuncs.ecs.model.v20140526.ModifyDiskAttributeRequest;
import com.aliyuncs.ecs.model.v20140526.ModifyDiskAttributeResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import org.apache.commons.collections4.CollectionUtils;

public class DiskRelated {
    static IAcsClient client;
    /** 
     * Specify the region ID of the preemptible instance. 
     */
    static String regionId = "cn-hangzhou";
    /**
     * Specify the ID of the preemptible instance. 
     */
    static String instanceId = "<your-instance-id>";
    public static void main(String[] args) {
        client = initialization();
        Disk disk = getDisks();
          if(null == disk){
            System.out.println("disk not exist");
            return;
        }
        String diskId = disk.getDiskId();
        modifyDiskAttribute(diskId);
        Boolean b = diskNotDeleteWithInstance();
        if(b){
            // Reconfigure the system disk not to be released along with the instance if the first-time configuration fails. 
            modifyDiskAttribute(diskId);
        }
    }

    /**
     * Query the details of the system disk. 
     */
    public static Disk getDisks(){
        DescribeDisksRequest request = new DescribeDisksRequest();
        request.setSysRegionId(regionId);
        request.setInstanceId(instanceId);
        request.setDiskType("system");
        try {
            DescribeDisksResponse response = client.getAcsResponse(request);
            if(CollectionUtils.isEmpty(response.getDisks())){
                System.out.println(("disk not exist. instanceId: " + instanceId));
                return null;
            }
            Disk disk = response.getDisks().get(0);
            return disk;
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Configure the system disk not to be released along with the instance. 
     */
    public static void modifyDiskAttribute(String diskId){
        ModifyDiskAttributeRequest request = new ModifyDiskAttributeRequest();
        request.setDeleteWithInstance(false);
        request.setSysRegionId(regionId);
        request.setDiskId(diskId);
        try {
            ModifyDiskAttributeResponse response = client.getAcsResponse(request);
            System.out.println(response.getRequestId());
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }

    /**
     * Check whether the system disk is configured to be released along with the instance. 
     */
    public static Boolean diskNotDeleteWithInstance(){
        Disk disks = getDisks();
        if (disks.getDeleteWithInstance()){
            System.out.println(("disk is delete with instance"));
        }else {
            System.out.println(("disk not delete with instance"));
        }
        return disks.getDeleteWithInstance();
    }

    private static IAcsClient initialization() {
        /**
         * Initialize request parameters. 
         * Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are configured. 
         * If the project code is leaked, the AccessKey pair may be leaked and the security of all resources in your account may be compromised. The following sample code shows how to use environment variables to obtain an AccessKey pair and use the AccessKey pair to call API operations. We recommend that you use Security Token Service (STS) tokens, which provide higher security. 
         */
        DefaultProfile profile = DefaultProfile.getProfile(regionId, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        return new DefaultAcsClient(profile);
    }
}

Use the ECS console

  1. Log on to the ECS console.

  2. In the left-side navigation pane, choose Instances & Images > Instances.

  3. In the top navigation bar, select the region and resource group to which the resource belongs. 地域

  4. On the Instance page, find the preemptible instance that you want to manage and click the ID of the instance.

  5. On the Instance Details page, click the Cloud Disk tab.

  6. Find the disk that you want to manage and choose 更多 > Modify Attributes in the Actions column.

  7. Clear Release Disk with Instance and click Confirm.

    关闭云盘随实例释放

Step 3: Configure a custom image to be created automatically when an interruption event is detected

After an interruption event of the preemptible instance is detected, the system uses Java code to create a snapshot for the system disk and create a custom image from the system disk snapshot.

In this step, the CreateSpotImage Java class is used. The following operations are called in sequence:

  • Call the DescribeInstances operation to query the state of the preemptible instance.

  • When an interruption event of the preemptible instance is detected, call the CreateSnapshot operation to create a snapshot for the system disk and then call the DescribeSnapshots operation to query the state of the snapshot.

  • After the system disk snapshot is created, call the CreateImage operation to create a custom image from the snapshot.

  • After the custom image is created, call the DescribeImages operation to query the state of the custom image. When the custom image enters the Available state, a message is returned.

import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.CreateImageRequest;
import com.aliyuncs.ecs.model.v20140526.CreateImageResponse;
import com.aliyuncs.ecs.model.v20140526.CreateSnapshotRequest;
import com.aliyuncs.ecs.model.v20140526.CreateSnapshotResponse;
import com.aliyuncs.ecs.model.v20140526.DescribeDisksRequest;
import com.aliyuncs.ecs.model.v20140526.DescribeDisksResponse;
import com.aliyuncs.ecs.model.v20140526.DescribeDisksResponse.Disk;
import com.aliyuncs.ecs.model.v20140526.DescribeImagesRequest;
import com.aliyuncs.ecs.model.v20140526.DescribeImagesResponse;
import com.aliyuncs.ecs.model.v20140526.DescribeInstancesRequest;
import com.aliyuncs.ecs.model.v20140526.DescribeInstancesResponse;
import com.aliyuncs.ecs.model.v20140526.DescribeInstancesResponse.Instance;
import com.aliyuncs.ecs.model.v20140526.DescribeSnapshotsRequest;
import com.aliyuncs.ecs.model.v20140526.DescribeSnapshotsResponse;
import com.aliyuncs.ecs.model.v20140526.DescribeSnapshotsResponse.Snapshot;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.common.collect.Lists;

/**
 * Monitor the interruption events of the preemptible instance. When an interruption event of the preemptible instance is detected, the system uses Java code to create a snapshot for the system disk and create a custom image from the system disk snapshot. 
 * The following operations are called in the Java code:
 * DescribeInstances: queries the details of the instance. 
 * CreateSnapshot: creates a snapshot for the system disk. 
 * DescribeSnapshots: queries the state of the system disk snapshot. 
 * CreateImage: creates a custom image. 
 * DescribeImages: queries the state of the custom image. 
 */
public class CreateSpotImage {
    static IAcsClient client;
    /**
     *  Specify the region ID of the preemptible instance. 
     */
    static String regionId = "cn-hangzhou";
    /**
     * Specify the ID of the preemptible instance. 
     */
    static String instanceId = "<your-instance-id>";

    public void main(String[] args) {
        client = initialization();
        // Step 1: Wait for the preemptible instance to enter the To Be Released state and an interruption event to be generated. 
        waitForInstanceMarked();
        String diskId = getDiskId();
        // Step 2: Create a snapshot for the system disk of the preemptible instance when an interruption event occurs on the preemptible instance. 
        String snapshotId = createSnapshot(diskId);
        // Step 3: Wait until the system disk snapshot is created. 
        waitCreateSnapshotSuccess(snapshotId);
        // Step 4: Create a custom image from the system disk snapshot. 
        String imageId = createImage(snapshotId);
        // Step 5: Wait until the custom image is created. 
        waitCreateImageSuccess(imageId);

    }

    /**
     *  Monitor the state of the preemptible instance and obtain the details of the instance when an interruption event occurs. 
     */
    public void waitForInstanceMarked() {
        // Convert the instance ID to a JSON string. 
        ArrayList<String> instanceIds = new ArrayList();
        DescribeInstancesResponse.Instance instance = null;
        instanceIds.add(instanceId);
        String instanceIdStr = JSON.toJSONString(instanceIds);
        boolean isMarked = false;
        // Determine whether an interruption event occurs on the preemptible instance. 
        while (!isMarked) {
            try {
                // Configure the parameters of the DescribeInstances operation and send the request. 
                DescribeInstancesRequest request = new DescribeInstancesRequest();
                // Specify the region ID of the preemptible instance. 
                request.setRegionId(regionId);
                // Specify the ID of the preemptible instance to query the details of the instance. 
                request.setInstanceIds(instanceIdStr);
                // Obtain the response. 
                DescribeInstancesResponse response = client.getAcsResponse(request);
                // Obtain the response data of the preemptible instance. 
                List<Instance> instanceList = response.getInstances();
                // If the details of the instance are not found, break out of the loop. 
                if (instanceList == null || instanceList.isEmpty()) {
                    break;
                }
                instance = instanceList.get(0);
                // If the instance is not interrupted, restart the loop. 
                if (instance.getOperationLocks() == null || instance.getOperationLocks().size() == 0) {
                    continue;
                }
                for (DescribeInstancesResponse.Instance.LockReason lockReason : instance.getOperationLocks()) {
                    // If the instance is interrupted, return the ID of the instance and the cause of the interruption. 
                    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();
            }
        }
    }

    /**
     * Query the details of the system disk of the preemptible instance. 
     */
    public static String getDiskId(){
        String diskId = null;
        DescribeDisksRequest request = new DescribeDisksRequest();
        request.setSysRegionId(regionId);
        request.setInstanceId(instanceId);
        request.setDiskType("system");
        try {
            DescribeDisksResponse response = client.getAcsResponse(request);
            List<Disk> disks = response.getDisks();
            if (null == disks || 0 == disks.size() ){
                System.out.println("disk not exist. instance: " + instanceId);
                return null;
            }
            Disk disk = disks.get(0);
            diskId = disk.getDiskId();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return diskId;
    }

    /**
     * Create a snapshot for the system disk. 
     */
    public static String createSnapshot(String diskId){
        CreateSnapshotRequest request = new CreateSnapshotRequest();
        request.setDiskId(diskId);
        request.setSnapshotName("disk_test");
        CreateSnapshotResponse response = null;
        try {
            response = client.getAcsResponse(request);
            System.out.println(JSON.toJSONString(response));
            System.out.println(response.getSnapshotId());
            return response.getSnapshotId();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return response.getSnapshotId();
    }

    /**
     * Check whether the system disk snapshot is created. 
     */
    public static void waitCreateSnapshotSuccess(String snapshotId){
        boolean isSuccess = false;
        while (!isSuccess) {
            Snapshot snapshot = describeSnapshots(snapshotId);
            if (null == snapshot) {
                System.err.println("image not exist. imageId: " + snapshotId);
                break;
            }
            if("accomplished".equals(snapshot.getStatus())){
                System.out.println("snapshot created successfully.");
                isSuccess = true;
            }
        }
    }

    /**
     * Call the DescribeSnapshots operation to query the state of the system disk snapshot. 
     */
    public static Snapshot describeSnapshots(String snapshotId){
        DescribeSnapshotsRequest request = new DescribeSnapshotsRequest();
        request.setSysRegionId(regionId);
        List<String> snapshotIds = Lists.newArrayList(snapshotId);
        String s = JSON.toJSONString(snapshotIds);
        request.setSnapshotIds(s);
        try {
            DescribeSnapshotsResponse response = client.getAcsResponse(request);
            if (null == response.getSnapshots() || response.getSnapshots().isEmpty()) {
                return null;
            }
            return response.getSnapshots().get(0);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *  Create a custom image. 
     */
    public static String createImage(String snapshotId) {
        try {
            // Configure the request parameters of the CreateImage operation and send the request. 
            CreateImageRequest request = new CreateImageRequest();
            request.setRegionId(regionId);
            request.setSnapshotId(snapshotId);
            request.setImageName("image_test");
            // Obtain the response and the ID of the custom image. 
            CreateImageResponse response = client.getAcsResponse(request);
            System.out.println("imageID:" + response.getImageId());
            return response.getImageId();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *  Check whether the custom image is created. 
     */
    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())) {
                System.out.println("Image created successfully.");
                isSuccess = true;
            }
        }
    }

    /**
     *  Call the DescribeImages operation to query the state of the custom image. 
     */
    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() {
       /**
         * Initialize request parameters. 
         * Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are configured. 
         * If the project code is leaked, the AccessKey pair may be leaked and the security of all resources in your account may be compromised. The following sample code shows how to use environment variables to obtain an AccessKey pair and then use the AccessKey pair to call API operations. The sample code is for reference only. We recommend that you use STS tokens, which provides higher security. 
         */
        DefaultProfile profile = DefaultProfile.getProfile(regionId, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        return new DefaultAcsClient(profile);
    }
}
            

Step 4: Create a preemptible instance from the custom image to restore data

In this step, the CreateSpotInstanceFromImage Java class is used. The following sample code provides an example on how to create a preemptible instance from the custom image by calling the RunInstances operation.

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;

/**
 *Call the RunInstances operation to create a preemptible instance. 
 */
public class CreateSpotInstanceFromImage {

    static IAcsClient client;
    /**
     *  Specify the ID of the region in which to create the instance. We recommend that you create the instance in the same region as the source preemptible instance. 
     */
    static String regionId = "cn-hangzhou";
    /**
     *  Specify the ID of the zone in which to create the instance. We recommend that you create the instance in the same zone as the source preemptible instance. 
     */
    static String zoneId = "cn-hangzhou-i";
    /**
     *  Specify the instance type of the preemptible instance. 
     */
    static String instanceType = "ecs.s6-c1m1.small";
    /**
     *  Specify the ID of a custom image. In this example, the ID of the custom image created in Step 3: Configure a custom image to be created automatically when an interruption event is detected is specified. 
     */
    static String imagesId = "<your-image-id>";
    /**
     *  Specify the ID of the vSwitch to which to connect the preemptible instance. 
     */
    static String vSwitchId = "<your-vsw-id>";
    /**
     *  Specify the ID of the security group to which to assign the preemptible instance. 
     */
    static String securityGroupId = "<your-sg-id>";
    /**
     *  Specify a preemption policy. 
     */
    static String spotStrategy = "SpotAsPriceGo";
    /**
     *  Specify the protection period of the preemptible instance. If you cannot determine the protection period, set the value to 0. 
     */
    static Integer spotDuration = 0;
    /**
     *  Specify the logon password of the preemptible instance. 
     */
    static String password = "<your-passwd>";

    public static void main(String[] args) {
        client = initialization();
        createInstance();
    }

    private static IAcsClient initialization() {
       /**
         * Initialize request parameters. 
         * Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are configured. 
         * If the project code is leaked, the AccessKey pair may be leaked and the security of all resources in your account may be compromised. The following sample code shows how to use environment variables to obtain an AccessKey pair and then use the AccessKey pair to call API operations. The sample code is for reference only. We recommend that you use STS tokens, which provides higher security. 
         */
        DefaultProfile profile = DefaultProfile.getProfile(regionId, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        return new DefaultAcsClient(profile);
    }

    /**
     * Call the RunInstances operation to create a preemptible instance. 
     */
    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("Instance ID: " + instanceId);
            return instanceId;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

References