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 state of the Cloud Assistant Agent, run a Cloud Assistant command, and query the execution results of the Cloud Assistant command.
Prerequisites
- The Cloud Assistant Agent is installed on the ECS instances that you want to manage. For more information, see Install the .
- The ECS instances are in the running state. For information about how to use SDK for Java to check the state 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 about the latest versions, visit MavenRepository.
- The shell, batch, or PowerShell command is compiled based on the instance configurations and the operations that you want to perform.
Background information
The Cloud Assistant Agent can remotely run commands only when it is in the running state. We recommend that you check the state of the Cloud Assistant Agent before you use it.Procedure
- 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.
- Create a RunCommandBestPractice class to run a Cloud Assistant command on one or more ECS instances. The RunCommandBestPractice class performs the following operations:
- Check the state of the Cloud Assistant Agent on ECS instances. The Cloud Assistant Agent can remotely run commands only when it is in the running state. In this step, the class checks whether the Cloud Assistant Agent is in the running state, and performs operations based on the check result:
- If the client is not in the running state, try again later.
- If the client is in the running state, go to the next step.
- 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 { //The IDs of one or more ECS instances. List<String> instanceIds = Arrays.asList("<yourInstanceId01>", "<yourInstanceId02>"); if (!checkCloudAssistantStatus(instanceIds)) { //After a timeout occurs, the 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 state of the Cloud Assistant Agent on the instances. * If a value of 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 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 the 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 the 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 the Cloud Assistant Agent is always in the not running state, we recommend that you troubleshoot the problem by performing the following operations:- Check whether the Cloud Assistant Agent is installed. By default, ECS instances created from public images after December 1, 2017 are pre-installed with the Cloud Assistant Agent. If the Cloud Assistant Agent is not installed on your instances, install the client. For more information, see Install the .
- Check the 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 the Cloud Assistant in the format of
https://{regionId}.axt.aliyun.com
. Replace {regionId} with the region ID of your instances.
A result similar to the following one is returned. Record InvokeId.{ "RequestId": "473469C7-AA6F-4DC5-B3DB-A3DC0DE3C83E", "InvokeId": "t-hz0b22o6******", "CommandId": "c-b224dc5072f3460fbb10fc2912******" }
- Check the state of the Cloud Assistant Agent on ECS instances.
- Create a DescribeInvocationsSample 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 execution 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()); } } }
Result
A result similar to the following one is returned. You can call the InvokeInstances operation to view the execution states 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"
}]
}]
}