十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Floci 本地模拟 AWS Batch:从任务编排到 Docker 执行的控制面实现解析

Floci 本地模拟 AWS Batch:从任务编排到 Docker 执行的控制面实现解析 Floci 本地模拟 AWS Batch从任务编排到 Docker 执行的控制面实现解析【免费下载链接】flociLight, fluffy, and always free - The AWS Local Emulator alternative项目地址: https://gitcode.com/gh_mirrors/fl/flociFlociLight, fluffy, and always free —— AWS Local Emulator在本地实现了 AWS Batch 控制面REST JSON 协议支持计算环境、任务队列、任务定义与任务提交等核心编排能力并可通过immediate与docker两种运行器模式完成本地契约测试或真实容器执行。本文以 docs/services/batch.md 为主线结合 BatchService.java、BatchDockerRunner.java、BatchController.java 等源码与 BatchIntegrationTest.java 测试带你掌握在 Floci 中配置与使用 AWS Batch 的完整实战方案包括数组任务Array Jobs、多节点并行任务MNP、EventBridge 联动与 CloudFormation 资源供给。Batch 服务的定位与端点约定Floci 的 Batch 实现面向本地集成测试的控制面模拟它完整保存队列、任务定义与任务的元数据让 SDK 调用可以像连真实 AWS 一样完成创建→提交→查询的闭环同时刻意简化为测试服务的调度语义如 immediate 模式下的即时成功。整体协议为REST JSON默认端点前缀为http://localhost:4566/v1/...。在源码层面所有端点由 BatchController.java 暴露统一走一个handle模板方法解析请求体空请求体视为{}通过 RegionResolver 解析请求区域然后将异常映射为带X-Amzn-Errortype头的 AWS 风格错误响应400ClientException、500ServerException。这意味着你的客户端错误处理逻辑在本地与云端行为一致。支持的操作Supported OperationsBatch 控制面共提供 12 个操作均以POST调用端点即 API 名小写化后的路径OperationEndpointDescriptionCreateComputeEnvironmentPOST /v1/createcomputeenvironment存储本地计算环境并返回其 ARNDescribeComputeEnvironmentsPOST /v1/describecomputeenvironments描述全部或选定的计算环境UpdateComputeEnvironmentPOST /v1/updatecomputeenvironment更新计算环境的状态、服务角色与计算资源DeleteComputeEnvironmentPOST /v1/deletecomputeenvironment删除处于DISABLED且未被任何任务队列引用的计算环境删除不存在的环境为无操作no-opCreateJobQueuePOST /v1/createjobqueue存储一个挂载到计算环境上的本地任务队列UpdateJobQueuePOST /v1/updatejobqueue更新任务队列的状态、优先级与计算环境顺序DeleteJobQueuePOST /v1/deletejobqueue删除处于DISABLED状态的任务队列删除不存在的队列为无操作DescribeJobQueuesPOST /v1/describejobqueues描述全部或选定的任务队列RegisterJobDefinitionPOST /v1/registerjobdefinition注册带修订号revision的container或multinode任务定义DeregisterJobDefinitionPOST /v1/deregisterjobdefinition将任务定义的某个修订标记为INACTIVEDescribeJobDefinitionsPOST /v1/describejobdefinitions按名称、ARN、修订号与状态列出任务定义SubmitJobPOST /v1/submitjob提交一个本地 Batch 任务DescribeJobsPOST /v1/describejobs按任务 ID 描述任务ListJobsPOST /v1/listjobs按队列、状态、AWSfilters与分页列出任务控制面的校验与细节从 BatchService.java 的实现可以看到一系列贴近 AWS 的契约细节计算环境type仅接受MANAGED/UNMANAGEDstate仅接受ENABLED/DISABLED创建后状态固定为VALID。UpdateComputeEnvironment对computeResources采用局部覆盖语义只覆盖调用方传入的字段如minvCpus/maxvCpus/desiredvCpus不重置整个子对象。删除前会校验状态为DISABLED且未被任何队列的computeEnvironmentOrder引用BatchService.java。任务队列priority为必填computeEnvironmentOrder中的每个环境必须是VALID状态删除ENABLED队列会报ClientExceptionBatchService.java。任务定义修订同名注册自动递增revisionARN 形如arn:aws:batch:region:account:job-definition/name:revisionDeregisterJobDefinition要求引用必须携带修订号name:revision或 ARN仅按名称引用会返回 400按名称提交时解析为最新 ACTIVE 修订BatchService.javaBatchIntegrationTest.java 完整验证了修订递增、注销与名称→最新修订解析行为。通用校验标签最多 50 个、键 1-128 字符且不能以aws:开头、值最多 256 字符环境变量名不能以AWS_BATCH开头timeout.attemptDurationSeconds最少 60 秒retryStrategy.attempts取值范围 1-10jobName需匹配[A-Za-z0-9][A-Za-z0-9_-]{0,127}。运行器模式Runner ModesBatch 的运行模式由配置项floci.services.batch.runner-mode环境变量FLOCI_SERVICES_BATCH_RUNNER_MODE控制在 EmulatorConfig.java 中定义默认值为immediate。值行为immediate默认值。SubmitJob持久化任务、记录生命周期时间戳、生成一个成功 attempt并在任务变为SUCCEEDED后返回。docker每个 attempt 从任务定义镜像启动一个 Docker 容器传入解析后的 command 与环境变量将MEMORY资源需求应用为容器内存上限捕获 CloudWatch Logs 日志流名称并根据容器退出码置为SUCCEEDED或FAILED。超时任务直接失败且不重试与 AWS Batch 的超时行为一致。process模式未实现。在immediate模式下运行循环仍然驱动任务完整经历状态机PENDING → RUNNABLE → STARTING → RUNNING随后生成退出码为 0 的 attemptBatchService.java。在docker模式下则调用 BatchDockerRunner.java 执行真实容器。Docker 运行器的实现细节BatchDockerRunner.java 是 docker 模式的核心执行引擎关键行为包括容器构建通过ContainerBuilder构建容器自动附加host.docker.internal或 Floci 内置 DNS 后缀以访问宿主机上的 Floci 端点、嵌入 DNS、日志轮转与资源标签command 为空时不传入 CMD。内置 AWS 环境每个容器注入AWS_REGION、AWS_ACCESS_KEY_IDtest、AWS_SECRET_ACCESS_KEYtest、AWS_SESSION_TOKENtest、FLOCI_ENDPOINT/AWS_ENDPOINT_URL指向 Floci 自身端口、AWS_BATCH_JOB_ID、AWS_BATCH_JOB_ATTEMPT、AWS_BATCH_JQ_NAME、AWS_BATCH_CE_NAMElocalBatchDockerRunner.java。内存限制遍历resourceRequirements仅将type MEMORY的需求解析为withMemoryMb应用非法数值会被忽略并告警。超时timeout.attemptDurationSeconds转换为容器等待期限超时返回退出码 137、reasonJob timed out且标记timedOuttrue从而驱动失败且不重试BatchDockerRunner.java。优雅清理运行中的容器记录在inFlightContainers映射中模拟器关闭SIGTERM时通过stopManagedContainers()回收避免中途退出导致孤儿容器。提交行为Submit BehaviorSubmitJob支持的字段如下jobNamejobDefinitionjobQueueparameterscontainerOverrides.commandcontainerOverrides.environmentarrayProperties.size数组任务nodeOverrides.numNodes、nodeOverrides.nodePropertyOverrides多节点并行任务timeout.attemptDurationSecondsretryStrategy.attemptstags关键合并与解析规则命令替换containerOverrides.command覆盖任务定义中的 command命令条目中的Ref::inputKey形式会在执行前从合并后的参数映射中解析为实际值BatchService.java。环境合并提交时的环境变量覆盖overrides逐键合并到任务定义环境变量之上definition 为底、overrides 为顶。不支持dependsOn任务依赖未实现提交时传入dependsOn会直接抛ClientExceptionBatchService.java。任务在本地的状态流转为SUBMITTED - PENDING - RUNNABLE - STARTING - RUNNING - SUCCEEDED|FAILEDimmediate 模式下每个任务强制经过PENDING是本地为测试做的简化——AWS 在无依赖、无容量等待时可能跳过该状态。集成测试 BatchIntegrationTest.java 验证了Ref::命令解析payloads/input.json等实际入参被注入 command、环境覆盖生效、attempt 记录退出码 0 等完整链路。重试与超时语义retryStrategy.attempts与timeout.attemptDurationSeconds均可由任务定义提供、SubmitJob 覆盖treeOrDefault语义。每次失败 attempt 后任务回到RUNNABLE并标记Attempt failed; retrying只有当 attempt 超时、达到最大尝试次数或退出码为 0 时才终态化BatchService.java。多节点任务的重试判定则完全由主节点结果驱动见下文。数组任务Array Jobs通过arrayProperties.size取值范围2-10,000提交即产生数组任务扇出模型每个索引生成一个子任务child共享父任务名称走与普通任务相同的执行管线在docker模式下每个子任务拥有独立容器。实时聚合父任务的status与arrayProperties.statusSummary并非增量存储而是在每次DescribeJobs/ListJobs调用时实时从子任务聚合计算arrayRollup方法BatchService.java因此大量子任务并发完成时不存在状态竞态。聚合规则任一子任务FAILED则父任务FAILED全部子任务SUCCEEDED则父任务SUCCEEDED否则按是否有子任务已离开SUBMITTED状态在PENDING/SUBMITTED之间选择startedAt取子任务最小值stoppedAt取最大值。列表视图队列级ListJobs对每个数组任务只显示一条记录父任务传入arrayJobId可列出子任务每个子任务附带arrayProperties.index。原子写入父任务与全部子任务在同一把锁内一次性写入读取方永远不会看到半成品数组BatchService.java。由于TerminateJob/CancelJob均未实现数组任务的级联取消不适用见 Limitations。多节点并行任务Multi-node Parallel, MNP注册type: multinode且带nodePropertiesnumNodes、mainNode、nodeRangeProperties的任务定义即为 MNP 任务定义对其SubmitJob可带nodeOverrides的行为并发执行docker模式下每个节点并发启动一个容器并注入AWS_BATCH_JOB_NODE_INDEX、AWS_BATCH_JOB_MAIN_NODE_INDEX、AWS_BATCH_JOB_NUM_NODES三个节点环境变量BatchDockerRunner.java。主节点裁决任务的最终状态、重试决策与startedAt/stoppedAt/statusReason完全由**主节点main node**决定——与 AWS 一致从节点失败不会导致任务失败或重试BatchService.java。节点范围解析nodeRangeProperties的targetNodes支持0:3、:3起点 0、4:到末节点或裸索引多个范围覆盖同一索引时按提交顺序最后一个覆盖生效对齐 AWS 的 nested ranges override注册时强制要求所有节点索引被完整覆盖BatchService.java。numNodes 覆盖nodeOverrides.numNodes允许扩缩节点数但要求任务定义中存在开放区间如n:且新节点数必须大于mainNode索引。描述视图DescribeJobs与队列级ListJobs返回整个任务一条记录带nodeProperties、无 per-nodecontainer传入multiNodeJobId调用ListJobs则按节点拆分每个节点带自己的container与nodeProperties.nodeIndex。约束MNP 任务定义不支持containerOverrides与数组任务请改用nodeOverridesBatchService.java。与 EventBridge 联动指向 Batch 任务队列的 EventBridge 规则目标可携带{ BatchParameters: { JobDefinition: my-job:1, JobName: nightly-job, ArrayProperties: {Size: 2}, RetryStrategy: {Attempts: 2} } }规则触发时Floci 通过submitFromEventBridge向目标队列提交一个等价 Batch 任务BatchService.java若目标负载包含根级Parameters对象其键值对会被字符串化并作为 Batch 提交参数传入扁平负载字段不会被转换为 Batch 参数。RetryStrategy.Attempts被映射为提交请求的retryStrategy.attempts。ArrayProperties会作为目标元数据被接受与回显用于本地部署兼容但 Batch 仍只提交一个本地任务不会扇出数组子任务——只有直接调用SubmitJob才能触发数组/MNP 展开见 Limitations。CloudFormation 资源供给Floci 为 Batch 提供以下 CloudFormation 资源类型的本地供给AWS::Batch::ComputeEnvironmentAWS::Batch::JobQueueAWS::Batch::JobDefinitionIAM 角色、VPC 字段、Fargate 声明、日志配置、存储与资源需求均作为元数据接受。docker 模式会把MEMORY需求应用为容器内存上限但本地调度不模拟AWS 的容量、VCPU 分配与 VPC 网络。注意CloudFormation 的AWS::Batch::JobDefinition供给器只注册container类型任务定义multinode任务定义只能通过直接调用RegisterJobDefinition供给见 Limitations。配置项ConfigurationBatch 的完整配置项如下源码定义于 EmulatorConfig.java变量默认值描述FLOCI_SERVICES_BATCH_ENABLEDtrue启用或禁用 Batch 服务FLOCI_SERVICES_BATCH_RUNNER_MODEimmediate运行器模式immediate或dockerFLOCI_SERVICES_BATCH_DOCKER_NETWORK(未设置)Batch 容器使用的 Docker 网络FLOCI_STORAGE_SERVICES_BATCH_MODE(继承全局)可选的存储模式覆盖FLOCI_STORAGE_SERVICES_BATCH_FLUSH_INTERVAL_MS5000持久化存储的刷盘间隔毫秒对应 YAML 配置方式application.yml可写作floci: services: batch: enabled: true runner-mode: immediate # 或 docker docker-network: my-batch-net storage: services: batch: mode: file flush-interval-ms: 5000存储实现Batch 的状态持久化由 BatchService.java 中的StorageFactory完成共四个存储后端batch-job-definitions.json任务定义按 ARN 索引batch-job-queues.json任务队列batch-compute-environments.json计算环境batch-jobs.json任务按 jobId 索引当存储后端为AccountAwareStorageBackend时任务的读写按账号accountId隔离getForAccount/putForAccount多账号测试场景下互不串扰。限制Limitations当前实现的边界与文档一致均可在源码中印证无 IAM 强制不校验任何 IAM 权限。无 VPC/子网/安全组模拟。无 AWS 忠实容量调度不模拟容量、VCPU 分配。无任务依赖dependsOn提交即报错。CancelJob与TerminateJob未实现普通任务、数组子任务、MNP 节点均无法取消/终止——这是与普通任务相同的既有缺口并非数组/MNP 引入的新问题。EventBridge input transformers走既有 EventBridge 目标输入路径Batch 专属的 input-transformer 完全对等未实现。MNP 结束时机差异AWS 在主节点退出时立即停止整个任务含剩余节点Floci 会等待每个节点容器都退出后才评定该 attempt因此存活时间超过主节点的从节点会让任务保持RUNNING更久。关闭这一差异需要BatchDockerRunner具备从节点自身运行循环外部停止其容器的能力当前不存在。数组/MNP 表面的已知后续项不影响SubmitJob/DescribeJobs/ListJobs的正确性刻意延后submitFromEventBridge不转发规则目标BatchParameters中的arrayProperties/nodeOverrides虽然ArrayProperties作为目标元数据被接受并回显EventBridge 触发的 Batch 任务今天无法扇出数组或运行 MNP只有直接SubmitJob可以。CloudFormation 的AWS::Batch::JobDefinition供给器只注册container类型无法通过 CloudFormation 供给multinode任务定义。ListJobs使用arrayJobId时忽略filters参数仅jobStatus对子任务生效——与 AWS 自身filters 不适用于子任务的说明一致但代价是数组子任务无法按JOB_NAME/JOB_DEFINITION等过滤。ListJobs使用multiNodeJobId时无分页maxResults/nextToken无效始终在一次响应中返回全部节点。实践建议契约测试首选immediate模式无需 Docker 环境即可完成注册定义→提交→描述/列出全链路毫秒级返回BatchIntegrationTest.java 展示了这类测试的典型写法。需要真实执行则切换docker模式任务会在独立容器中真实运行借助注入的AWS_ENDPOINT_URL可访问 Floci 上其他模拟服务适合端到端验证记得为 Batch 容器规划 Docker 网络与镜像拉取策略。用数组/MNP 覆盖并行场景数组任务适合参数化扇出2-10,000MNP 适合多节点协同主节点裁决注意 EventBridge 触发的任务暂不支持这两者。关注超时与重试timeout.attemptDurationSeconds最小 60 秒、retryStrategy.attempts最大 10docker 模式超时任务以 137 退出且不重试。参考文件索引服务文档docs/services/batch.mdHTTP 端点层BatchController.java控制面核心逻辑BatchService.javaDocker 执行器BatchDockerRunner.java配置定义EmulatorConfig.java集成测试BatchIntegrationTest.java、BatchServiceTest.java、BatchDockerRunnerTest.java【免费下载链接】flociLight, fluffy, and always free - The AWS Local Emulator alternative项目地址: https://gitcode.com/gh_mirrors/fl/floci创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表