关于 azure-compute-batch-java
面向 Java 的技能,介绍如何使用 Azure Batch SDK 管理计算池、作业和任务,以运行并行及高性能计算工作负载。内容涵盖同步与异步客户端、任务提交、调度和监控。
主要功能
- 01创建和管理计算池
- 02创建并跟踪作业与任务
- 03批量提交任务集合
- 04配置自动缩放和计划
- 05查看任务结果与输出
适用场景
- 01在 Azure Batch 上运行并行工作负载
- 02提交大量相关计算任务
- 03监控作业进度并获取任务输出
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill azure-compute-batch-java安装后在 Claude Code 中输入/azure-compute-batch-java确认已加载。
详细介绍
原文在翻译后有更新,译文可能不是最新。
Azure Batch SDK for Java
用于在 Azure 中运行大规模并行和高性能计算 (HPC) 批处理作业的客户端库。
安装
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-compute-batch</artifactId>
<version>1.0.0-beta.5</version>
</dependency>
先决条件
- Azure Batch 账户
- 配置了计算节点的池
- Azure 订阅
环境变量
AZURE_BATCH_ENDPOINT=https://<account>.<region>.batch.azure.com
AZURE_BATCH_ACCOUNT=<account-name>
AZURE_BATCH_ACCESS_KEY=<account-key>
创建客户端
使用 Microsoft Entra ID(推荐)
import com.azure.compute.batch.BatchClient;
import com.azure.compute.batch.BatchClientBuilder;
import com.azure.identity.DefaultAzureCredentialBuilder;
BatchClient batchClient = new BatchClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
.buildClient();
异步客户端
import com.azure.compute.batch.BatchAsyncClient;
BatchAsyncClient batchAsyncClient = new BatchClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
.buildAsyncClient();
使用共享密钥凭据
import com.azure.core.credential.AzureNamedKeyCredential;
String accountName = System.getenv("AZURE_BATCH_ACCOUNT");
String accountKey = System.getenv("AZURE_BATCH_ACCESS_KEY");
AzureNamedKeyCredential sharedKeyCreds = new AzureNamedKeyCredential(accountName, accountKey);
BatchClient batchClient = new BatchClientBuilder()
.credential(sharedKeyCreds)
.endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
.buildClient();
关键概念
| 概念 | 描述 |
|---|---|
| 池 | 运行任务的计算节点集合 |
| 作业 | 任务的逻辑分组 |
| 任务 | 计算单元(命令/脚本) |
| 节点 | 执行任务的 VM |
| 作业计划 | 定期创建作业 |
池操作
创建池
import com.azure.compute.batch.models.*;
batchClient.createPool(new BatchPoolCreateParameters("myPoolId", "STANDARD_DC2s_V2")
.setVirtualMachineConfiguration(
new VirtualMachineConfiguration(
new BatchVmImageReference()
.setPublisher("Canonical")
.setOffer("UbuntuServer")
.setSku("22_04-lts")
.setVersion("latest"),
"batch.node.ubuntu 22.04"))
.setTargetDedicatedNodes(2)
.setTargetLowPriorityNodes(0), null);
获取池
BatchPool pool = batchClient.getPool("myPoolId");
System.out.println("Pool state: " + pool.getState());
System.out.println("Current dedicated nodes: " + pool.getCurrentDedicatedNodes());
列出池
import com.azure.core.http.rest.PagedIterable;
PagedIterable<BatchPool> pools = batchClient.listPools();
for (BatchPool pool : pools) {
System.out.println("Pool: " + pool.getId() + ", State: " + pool.getState());
}
调整池大小
import com.azure.core.util.polling.SyncPoller;
BatchPoolResizeParameters resizeParams = new BatchPoolResizeParameters()
.setTargetDedicatedNodes(4)
.setTargetLowPriorityNodes(2);
SyncPoller<BatchPool, BatchPool> poller = batchClient.beginResizePool("myPoolId", resizeParams);
poller.waitForCompletion();
BatchPool resizedPool = poller.getFinalResult();
启用自动缩放
BatchPoolEnableAutoScaleParameters autoScaleParams = new BatchPoolEnableAutoScaleParameters()
.setAutoScaleEvaluationInterval(Duration.ofMinutes(5))
.setAutoScaleFormula("$TargetDedicatedNodes = min(10, $PendingTasks.GetSample(TimeInterval_Minute * 5));");
batchClient.enablePoolAutoScale("myPoolId", autoScaleParams);
删除池
SyncPoller<BatchPool, Void> deletePoller = batchClient.beginDeletePool("myPoolId");
deletePoller.waitForCompletion();
作业操作
创建作业
batchClient.createJob(
new BatchJobCreateParameters("myJobId", new BatchPoolInfo().setPoolId("myPoolId"))
.setPriority(100)
.setConstraints(new BatchJobConstraints()
.setMaxWallClockTime(Duration.ofHours(24))
.setMaxTaskRetryCount(3)),
null);
获取作业
BatchJob job = batchClient.getJob("myJobId", null, null);
System.out.println("Job state: " + job.getState());
列出作业
PagedIterable<BatchJob> jobs = batchClient.listJobs(new BatchJobsListOptions());
for (BatchJob job : jobs) {
System.out.println("Job: " + job.getId() + ", State: " + job.getState());
}
获取任务计数
BatchTaskCountsResult counts = batchClient.getJobTaskCounts("myJobId");
System.out.println("Active: " + counts.getTaskCounts().getActive());
System.out.println("Running: " + counts.getTaskCounts().getRunning());
System.out.println("Completed: " + counts.getTaskCounts().getCompleted());
终止作业
BatchJobTerminateParameters terminateParams = new BatchJobTerminateParameters()
.setTerminationReason("Manual termination");
BatchJobTerminateOptions options = new BatchJobTerminateOptions().setParameters(terminateParams);
SyncPoller<BatchJob, BatchJob> poller = batchClient.beginTerminateJob("myJobId", options, null);
poller.waitForCompletion();
删除作业
SyncPoller<BatchJob, Void> deletePoller = batchClient.beginDeleteJob("myJobId");
deletePoller.waitForCompletion();
任务操作
创建单个任务
BatchTaskCreateParameters task = new BatchTaskCreateParameters("task1", "echo 'Hello World'");
batchClient.createTask("myJobId", task);
创建带退出条件的任务
batchClient.createTask("myJobId", new BatchTaskCreateParameters("task2", "cmd /c exit 3")
.setExitConditions(new ExitConditions()
.setExitCodeRanges(Arrays.asList(
new ExitCodeRangeMapping(2, 4,
new ExitOptions().setJobAction(BatchJobActionKind.TERMINATE)))))
.setUserIdentity(new UserIdentity()
.setAutoUser(new AutoUserSpecification()
.setScope(AutoUserScope.TASK)
.setElevationLevel(ElevationLevel.NON_ADMIN))),
null);
创建任务集合(最多 100 个)
List<BatchTaskCreateParameters> taskList = Arrays.asList(
new BatchTaskCreateParameters("task1", "echo Task 1"),
new BatchTaskCreateParameters("task2", "echo Task 2"),
new BatchTaskCreateParameters("task3", "echo Task 3")
);
BatchTaskGroup taskGroup = new BatchTaskGroup(taskList);
BatchCreateTaskCollectionResult result = batchClient.createTaskCollection("myJobId", taskGroup);
创建多个任务(无限制)
List<BatchTaskCreateParameters> tasks = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
tasks.add(new BatchTaskCreateParameters("task" + i, "echo Task " + i));
}
batchClient.createTasks("myJobId", tasks);
获取任务
BatchTask task = batchClient.getTask("myJobId", "task1");
System.out.println("Task state: " + task.getState());
System.out.println("Exit code: " + task.getExecutionInfo().getExitCode());
列出任务
PagedIterable<BatchTask> tasks = batchClient.listTasks("myJobId");
for (BatchTask task : tasks) {
System.out.println("Task: " + task.getId() + ", State: " + task.getState());
}
获取任务输出
import com.azure.core.util.BinaryData;
import java.nio.charset.StandardCharsets;
BinaryData stdout = batchClient.getTaskFile("myJobId", "task1", "stdout.txt");
System.out.println(new String(stdout.toBytes(), StandardCharsets.UTF_8));
终止任务
batchClient.terminateTask("myJobId", "task1", null, null);
节点操作
列出节点
PagedIterable<BatchNode> nodes = batchClient.listNodes("myPoolId", new BatchNodesListOptions());
for (BatchNode node : nodes) {
System.out.println("Node: " + node.getId() + ", State: " + node.getState());
}
重启节点
SyncPoller<BatchNode, BatchNode> rebootPoller = batchClient.beginRebootNode("myPoolId", "nodeId");
rebootPoller.waitForCompletion();
获取远程登录设置
BatchNodeRemoteLoginSettings settings = batchClient.getNodeRemoteLoginSettings("myPoolId", "nodeId");
System.out.println("IP: " + settings.getRemoteLoginIpAddress());
System.out.println("Port: " + settings.getRemoteLoginPort());
作业计划操作
创建作业计划
batchClient.createJobSchedule(new BatchJobScheduleCreateParameters("myScheduleId",
new BatchJobScheduleConfiguration()
.setRecurrenceInterval(Duration.ofHours(6))
.setDoNotRunUntil(OffsetDateTime.now().plusDays(1)),
new BatchJobSpecification(new BatchPoolInfo().setPoolId("myPoolId"))
.setPriority(50)),
null);
获取作业计划
BatchJobSchedule schedule = batchClient.getJobSchedule("myScheduleId");
System.out.println("Schedule state: " + schedule.getState());
错误处理
import com.azure.compute.batch.models.BatchErrorException;
import com.azure.compute.batch.models.BatchError;
try {
batchClient.getPool("nonexistent-pool");
} catch (BatchErrorException e) {
BatchError error = e.getValue();
System.err.println("Error code: " + error.getCode());
System.err.println("Message: " + error.getMessage().getValue());
if ("PoolNotFound".equals(error.getCode())) {
System.err.println("The specified pool does not exist.");
}
}
最佳实践
- 使用 Entra ID — 优先于共享密钥进行身份验证
- 使用管理 SDK 管理池 —
azure-resourcemanager-batch支持托管标识 - 批量创建任务 — 对多个任务使用
createTaskCollection或createTasks - 正确处理 LRO — 池调整大小、删除操作是长时间运行的
- 监控任务计数 — 使用
getJobTaskCounts跟踪进度 - 设置约束 — 配置
maxWallClockTime和maxTaskRetryCount - 使用低优先级节点 — 为容错工作负载节省成本
- 启用自动缩放 — 根据工作负载动态调整池大小
参考链接
何时使用
此技能适用于执行概述中描述的工作流或操作。
限制
- 仅当任务明确符合上述范围时才使用此技能。
- 请勿将输出视为特定环境验证、测试或专家评审的替代品。
- 如果缺少必需的输入、权限、安全边界或成功标准,请停止并请求澄清。
评论
支持 Markdown