雲助手命令可以在多台ECS執行個體中批量執行Shell、Bat或者PowerShell指令碼。本文介紹如何通過Java SDK檢測雲助手Agent狀態、運行雲助手命令和查詢雲助手命令執行結果。
前提條件
目標ECS執行個體已安裝雲助手Agent。具體操作,請參見安裝雲助手Agent。
請確保代碼運行環境設定了環境變數ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。具體配置方法,請參見在Linux、macOS和Windows系統配置環境變數。
ECS執行個體狀態必須為運行中(
Running
)。關於如何使用Java SDK查詢執行個體的狀態,請參見查詢ECS執行個體。已在開發環境中安裝Java SDK2.0,您需要在Maven專案中添加依賴。更多詳情,請前往Maven專案擷取最新版本。
根據ECS執行個體的配置,以及您需要執行的操作,準備好雲助手使用的命令(Shell、Bat或者PowerShell命令)。
操作步驟
擷取阿里雲帳號AccessKey,以及查詢地區ID。
具體操作,請參見地區和可用性區域和建立AccessKey。
建立一個RunCommandBestPractice類,為一台或多台的ECS執行個體執行雲助手命令。
RunCommandBestPractice類主要實現以下功能:
檢查雲助手Agent的運行狀態。
雲助手Agent只有在運行中狀態時,才支援遠程執行命令。此步驟先檢查雲助手Agent狀態是否為運行中,並根據檢查結果判斷下一步操作:
如果不是運行中,則等待並重試。
如果是運行中,則執行下一步。
執行雲助手命令。
範例程式碼如下所示:
import com.aliyun.auth.credentials.Credential; import com.aliyun.auth.credentials.provider.StaticCredentialProvider; import com.aliyun.sdk.service.ecs20140526.models.RunCommandRequest; import com.aliyun.sdk.service.ecs20140526.models.RunCommandResponse; import com.aliyun.sdk.service.ecs20140526.AsyncClient; import com.google.gson.Gson; import darabonba.core.client.ClientOverrideConfiguration; import java.util.concurrent.CompletableFuture; public class RunCommand { public static void main(String[] args) throws Exception { // 配置憑證資訊,包括 AK、Secret 和 Token StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder() // 確保環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET 本地環境已設定。 .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")) .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")) //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // 使用 STS Token .build()); // 配置用戶端 AsyncClient client = AsyncClient.builder() // 設定地區 ID使用者需要手動填寫 .region("cn-nanjing") // 使用配置好的 HttpClient,否則使用預設的 HttpClient (Apache HttpClient) .credentialsProvider(provider) // 服務等級的配置 // 用戶端層級的配置重寫,可以設定 Endpoint、HTTP 要求參數等 .overrideConfiguration( ClientOverrideConfiguration.create() // Endpoint 可以在 https://api.aliyun.com/product/Ecs 查看 .setEndpointOverride("ecs.cn-nanjing.aliyuncs.com") ) .build(); // 設定 API 請求的參數 RunCommandRequest runCommandRequest = RunCommandRequest.builder() // 地區 ID .regionId("cn-nanjing") // 命令類型 .type("RunShellScript") .commandContent("yourScript") // 要執行的指令碼內容 .instanceId(java.util.Arrays.asList( // 執行個體 ID 列表使用者手動輸入 "i-gc75qem27b6n******" )) // 請求層級的配置重寫,可以設定 HTTP 要求參數等 // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders())) .build(); // 非同步擷取 API 請求的傳回值 CompletableFuture<RunCommandResponse> response = client.runCommand(runCommandRequest); // 同步擷取 API 請求的傳回值 RunCommandResponse resp = response.get(); System.out.println(new Gson().toJson(resp)); // 關閉用戶端 client.close(); } }
說明如果雲助手Agent狀態一直為未運行,建議您從以下幾方面進行排查:
檢查是否安裝了雲助手Agent。2017年12月01日之後使用公用鏡像建立的ECS執行個體,預設預裝雲助手Agent。如果您的執行個體未安裝雲助手Agent,請先手動安裝。具體操作,請參見安裝雲助手Agent。
檢查網路設定。請您確保在執行個體中,能夠正常地進行網域名稱解析和網路請求,並且能夠訪問雲助手服務地址(
https://{regionId}.axt.aliyun.com
,其中{regionId}改為您的執行個體所在地區)。
返回結果如下所示,並記錄InvokeId。
{ "headers":{ "Keep-Alive":"timeout=25", "Access-Control-Expose-Headers":"*", "Access-Control-Allow-Origin":"*", "ETag":"1CT+jOmffBsGnpxVQRtwUaw5", "x-acs-request-id":"E14423A1-4D3C-5FA9-BE6D-E5D9E******", "Connection":"keep-alive", "Content-Length":"115", "Date":"Tue, 30 Jul 2024 05:28:59 GMT", "Content-Type":"application/json;charset=utf-8", "x-acs-trace-id":"1e73536caf966986c0de6******" }, "statusCode":200, "body":{ "commandId":"c-nj04s3ja******", "invokeId":"t-nj04s3j******", "requestId":"E14423A1-4D3C-5FA9-BE6D-E5D9E******" } }
建立一個DescribeInvocationsSample類,查詢命令運行是否成功。
import com.aliyun.auth.credentials.Credential; import com.aliyun.auth.credentials.provider.StaticCredentialProvider; import com.aliyun.sdk.service.ecs20140526.models.*; import com.aliyun.sdk.service.ecs20140526.*; import com.google.gson.Gson; import darabonba.core.client.ClientOverrideConfiguration; import java.util.concurrent.CompletableFuture; public class DescribeInvocations { public static void main(String[] args) throws Exception { StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder() // 確保環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET 本地環境已設定。 .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")) .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")) .build()); AsyncClient client = AsyncClient.builder() // 設定地區 ID使用者需要手動填寫 .region("cn-nanjing") .credentialsProvider(provider) .overrideConfiguration( ClientOverrideConfiguration.create() // Endpoint 請參考 https://api.aliyun.com/product/Ecs .setEndpointOverride("ecs.cn-nanjing.aliyuncs.com") ) .build(); DescribeInvocationsRequest describeInvocationsRequest = DescribeInvocationsRequest.builder() .regionId("cn-nanjing") // 執行 ID使用者自己手動填寫 .invokeId("t-nj04s3ja******") .build(); CompletableFuture<DescribeInvocationsResponse> response = client.describeInvocations(describeInvocationsRequest); DescribeInvocationsResponse resp = response.get(); System.out.println(new Gson().toJson(resp)); client.close(); } }
執行結果
返回結果如下所示,通過InvokeInstances,您可以查看命令的運行狀態和結果。更多資訊,請參見DescribeInvocations。
{
"body":{
"invocations":{
"invocation":[
{
"commandContent":"eW91clNjc******",
"commandDescription":"",
"commandId":"c-nj04s3j******",
"commandName":"cmd-2024-07-30",
"commandType":"RunShellScript",
"containerId":"",
"containerName":"",
"creationTime":"2024-07-30T05:28:59Z",
"frequency":"",
"invocationStatus":"Failed",
"invokeId":"t-nj04s3******",
"invokeInstances":{
"invokeInstance":[
{
"creationTime":"2024-07-30T05:28:59Z",
"dropped":0,
"errorCode":"ExitCodeNonzero",
"errorInfo":"the command execution exit code is not zero.",
"exitCode":127,
"finishTime":"2024-07-30T05:29:01Z",
"instanceId":"i-gc75qem27b6n5******",
"instanceInvokeStatus":"Finished",
"invocationStatus":"Failed",
"output":******
"repeats":1,
"startTime":"2024-07-30T05:29:00Z",
"stopTime":"",
"timed":false,
"updateTime":"2024-07-30T05:29:01Z"
}
]
},
"invokeStatus":"Finished",
"parameters":"{}",
"repeatMode":"Once",
"tags":{
"tag":[]
},
"terminationMode":"Process",
"timed":false,
"timeout":60,
"username":"",
"workingDir":""
}
]
},
"nextToken":"",
"pageNumber":1,
"pageSize":10,
"requestId":"7AB4D3FF-E251-5235-99C4-1A18099E0F01",
"totalCount":1
},
"headers":{
"Access-Control-Allow-Origin":"*",
"Access-Control-Expose-Headers":"*",
"Connection":"keep-alive",
"Content-Length":"1207",
"Content-Type":"application/json;charset=utf-8",
"Date":"Tue, 30 Jul 2024 05:41:14 GMT",
"ETag":"13/WTudylqHr+WPQBunND8g7",
"Keep-Alive":"timeout=25",
"Vary":"Accept-Encoding",
"x-acs-request-id":"7AB4D3FF-E251-5235-99C4******",
"x-acs-trace-id":"028dd251acfb4dbfceac9b56e******f"
},
"statusCode":200
}