All Products
Search
Document Center

Elastic Compute Service:Use Java to manage ECS instances without logging on to the instances

Last Updated:Jun 21, 2023

You can use Cloud Assistant to simultaneously run a command on multiple Elastic Compute Service (ECS) instances. The command can be a shell, batch, or PowerShell command. This topic describes how to use SDK for Java to check the status of Cloud Assistant Agent, run a Cloud Assistant command, and query the executions results of the Cloud Assistant command.

Prerequisites

  • Cloud Assistant Agent is installed on the ECS instances that you want to manage. For more information, see Install Cloud Assistant Agent.

  • The ECS instances must be in the Running (Running) state. For information about how to use SDK for Java to check the status of ECS instances, see Query an ECS instance.

  • The aliyun-java-sdk-ecs SDK dependency in Java is updated to V4.18.3 or later. For more information, see maven repository.

  • The shell, batch, or PowerShell command is compiled based on the instance configurations and the operations that you want to perform.

Procedure

  1. Obtain the AccessKey pair (AccessKey ID and AccessKey secret) of your account and query the region ID.

    For more information, see Regions and zones and Obtain an AccessKey pair.

  2. Create a RunCommandBestPractice class to run a Cloud Assistant command on one or more ECS instances.

    The RunCommandBestPractice class performs the following actions:

    1. Check the status of Cloud Assistant Agent.

      Cloud Assistant Agent can run remote commands only when it is in the Running state. In this step, the class checks whether Cloud Assistant Agent is in the Running state, and takes action based on the check result:

      • If Cloud Assistant Agent is not in the Running state, try again later.

      • If Cloud Assistant Agent is in the Running state, go to the next step.

    2. Run a Cloud Assistant command on ECS instances.

    Sample code:

    import com.aliyuncs.AcsResponse;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.RpcAcsRequest;
    import com.aliyuncs.ecs.model.v20140526.DescribeCloudAssistantStatusRequest;
    import com.aliyuncs.ecs.model.v20140526.DescribeCloudAssistantStatusResponse;
    import com.aliyuncs.ecs.model.v20140526.RunCommandRequest;
    import com.aliyuncs.ecs.model.v20140526.RunCommandResponse;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.google.gson.Gson;
    
    import java.util.Arrays;
    import java.util.List;
    
    public class RunCommandBestPractice {
        private static final int MAX_RETRIES = 2;
        private static final long MAX_WAIT_INTERVAL = 20000L;
        private static final long TIME_OUT = 60L;
    
        public static void main(String[] args) throws InterruptedException {
            //Specify the IDs of one or more ECS instances. 
            List<String> instanceIds = Arrays.asList("<yourInstanceId01>", "<yourInstanceId02>");
    
            if (!checkCloudAssistantStatus(instanceIds)) {
                //After a timeout occurs, Cloud Assistant Agent is still not in the running state. 
                //Handle the exception or proceed to call the RunCommand operation. 
            }
    
            RunCommandResponse runCommandResponse = runCommand(instanceIds);
            System.out.println(new Gson().toJson(runCommandResponse));
            //Call the DescribeInvocations operation to check the execution results of the Cloud Assistant command. 
        }
    
        /**
         * Check the status of Cloud Assistant Agent. 
         * If false is returned, try again later. 
         * @param instanceIds
         * @return
         * @throws InterruptedException
         */
        private static boolean checkCloudAssistantStatus(List<String> instanceIds) throws InterruptedException {
            int retryTimes = 0;
            boolean retry = false;
            do {
                long waitTime = Math.min(getWaitInternal(retryTimes), MAX_WAIT_INTERVAL);
                Thread.sleep(waitTime);
                DescribeCloudAssistantStatusResponse describeCloudAssistantStatusResponse = describeCloudAssistantStatus(instanceIds);
                if (describeCloudAssistantStatusResponse == null) {
                    //Handle exceptions such as the exception thrown when specified instances do not exist or when specified instances are in the Stopped state. 
                    retry = false;
                } else {
                    for (DescribeCloudAssistantStatusResponse.InstanceCloudAssistantStatus instanceCloudAssistantStatus :
                            describeCloudAssistantStatusResponse.getInstanceCloudAssistantStatusSet()) {
                        if ("false".equals(instanceCloudAssistantStatus.getCloudAssistantStatus())) {
                            retry = true;
                            break;
                        }
                    }
                }
            } while (retry && (retryTimes++ < MAX_RETRIES));
    
            return retryTimes <= MAX_RETRIES;
        }
    
        /**
         * Call the DescribeCloudAssistantStatus operation to check whether Cloud Assistant Agent is installed on the instances. 
         * @param instanceIds
         * @return
         */
        private static DescribeCloudAssistantStatusResponse describeCloudAssistantStatus(List<String> instanceIds) {
            DescribeCloudAssistantStatusRequest describeCloudAssistantStatusRequest = new DescribeCloudAssistantStatusRequest();
            describeCloudAssistantStatusRequest.setInstanceIds(instanceIds);
            return sendRequest(describeCloudAssistantStatusRequest);
        }
    
        /**
         * Call the RunCommand operation to run a Cloud Assistant command.
         * @param instanceIds
         * @return
         */
        private static RunCommandResponse runCommand(List<String> instanceIds) {
            RunCommandRequest runCommandRequest = new RunCommandRequest();
            //Edit the Cloud Assistant command. 
            runCommandRequest.setCommandContent("<yourScript>");
            runCommandRequest.setInstanceIds(instanceIds);
            runCommandRequest.setType("RunShellScript");
            runCommandRequest.setTimeout(TIME_OUT);
            return sendRequest(runCommandRequest);
        }
    
        /**
         * Use the exponential backoff algorithm to obtain the retry interval.
         * @param retryTime
         * @return
         */
        private static long getWaitInternal(int retryTime) {
            return (long)(Math.pow(2, retryTime) * 1000L);
        }
    
        private static <T extends AcsResponse> T sendRequest(RpcAcsRequest<T> request) {
            //Initialize the profile object and configure the region ID (Example: cn-hangzhou) and the AccessKey pair. 
            DefaultProfile profile = DefaultProfile.getProfile("<yourRegionId>", "<yourAccessKeyId>", "<yourAccessKeySecret>");
            IAcsClient client = new DefaultAcsClient(profile);
            try {
                T response = client.getAcsResponse(request);
                return response;
            } catch (ServerException e) {
                //Handle 5XX errors.
                e.printStackTrace();
            } catch (ClientException e) {
                //Handle 4XX errors.
                System.out.println("ErrCode:" + e.getErrCode());
                System.out.println("ErrMsg:" + e.getErrMsg());
                System.out.println("RequestId:" + e.getRequestId());
            }
            return null;
        }
    }
    Note

    If Cloud Assistant Agent remains in a non-running state, we recommend that you troubleshoot the issue by performing the following operations:

    • Check whether Cloud Assistant Agent is installed. By default, ECS instances that are created from public images after December 1, 2017 are pre-installed with Cloud Assistant Agent. If Cloud Assistant Agent is not installed on your instance, install Cloud Assistant Agent on the instance. For more information, see Install Cloud Assistant Agent.

    • Check network configurations. Make sure that you can perform domain name resolution or make network requests on the instances and that you can access the endpoint of Cloud Assistant in the format of https://{regionId}.axt.aliyun.com. Replace {regionId} with the region ID of your instance.

    A response similar to the following one is returned. Record InvokeId, which indicates the task ID of the Cloud Assistant command.

    {
        "RequestId": "473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E",
        "InvokeId": "t-hz0b22o6******",
        "CommandId": "c-b224dc5072f3460fbb10fc2912******"
    }
  3. Create a DescribeInvocationsSample.java class to check whether the command is executed.

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.ecs.model.v20140526.DescribeInvocationsRequest;
    import com.aliyuncs.ecs.model.v20140526.DescribeInvocationsResponse;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.google.gson.Gson;
    
    public class DescribeInvocationsSample {
        public static void main(String[] args) {
            DefaultProfile profile = DefaultProfile.getProfile("<yourRegionId>", "<yourAccessKeyId>", "<yourAccessKeySecret>");
            IAcsClient client = new DefaultAcsClient(profile);
    
            DescribeInvocationsRequest request = new DescribeInvocationsRequest();
            //Enter the task ID of the Cloud Assistant command. 
            request.setInvokeId("t-hz0b22o6******");
    
            try {
                DescribeInvocationsResponse response = client.getAcsResponse(request);
                System.out.println(new Gson().toJson(response));
            } catch (ServerException e) {
                e.printStackTrace();
            } catch (ClientException e) {
                System.out.println("ErrCode:" + e.getErrCode());
                System.out.println("ErrMsg:" + e.getErrMsg());
                System.out.println("RequestId:" + e.getRequestId());
            }
        }
    }

Response

A response similar to the following one is returned. You can call the InvokeInstances operation to view the execution status and results of the command. For more information, see DescribeInvocations.

{
    "requestId": "42837BE9-1230-4E66-A21C-EC11C24221A3",
    "totalCount": 1,
    "pageNumber": 1,
    "pageSize": 10,
    "invocations": [{
        "invokeId": "t-hz0b22o6******",
        "creationTime": "2021-01-07T10:11:03Z",
        "commandId": "c-hz0179jxlag****",
        "commandType": "RunShellScript",
        "commandName": "cmd-2021-01-07",
        "commandContent": "******",
        "frequency": "",
        "timed": false,
        "invokeStatus": "PartialFailed",
        "invocationStatus": "PartialFailed",
        "parameters": "{}",
        "username": "",
        "invokeInstances": [{
            "instanceId": "i-bp11entzst4xwyb******",
            "repeats": 1,
            "instanceInvokeStatus": "Finished",
            "invocationStatus": "Success",
            "output": "******",
            "exitCode": 0,
            "dropped": 0,
            "errorCode": "",
            "errorInfo": "",
            "creationTime": "2021-01-07T10:11:03Z",
            "startTime": "2021-01-07T10:11:04Z",
            "stopTime": "",
            "finishTime": "2021-01-07T10:11:05Z",
            "updateTime": "2021-01-07T10:11:05Z"
        }, {
            "instanceId": "i-bp1ida94x2133l******",
            "repeats": 1,
            "instanceInvokeStatus": "Failed",
            "invocationStatus": "Timeout",
            "output": "******",
            "dropped": 49259,
            "errorCode": "ExecutionTimeout",
            "errorInfo": "the command execution has been timeout.",
            "creationTime": "2021-01-07T10:11:03Z",
            "startTime": "2021-01-07T10:11:04Z",
            "stopTime": "",
            "finishTime": "2021-01-07T10:12:04Z",
            "updateTime": "2021-01-07T10:12:04Z"
        }]
    }]
}