Azure Batch 最佳做法

本文介绍有关有效使用 Azure Batch 服务的最佳做法和有用技巧。 这些技巧可帮助您提升性能,并避免在 Batch 解决方案中陷入设计误区。

是用于在 Batch 服务上执行作业的计算资源。 以下各节提供了关于如何使用 Batch 池的建议。

池配置和命名

  • 池分配模式: 创建 Batch 帐户时,可以在两种池分配模式之间进行选择:Batch 服务用户订阅。 在大多数情况下,应使用默认的 Batch 服务模式,在该模式下,池会在 Batch 管理的订阅中于后台进行分配。 在备用的“用户订阅”模式下,会在创建池后直接在订阅中创建 Batch VM 和其他资源。 用户订阅帐户主要用于实现一小部分但又非常重要的方案。 有关详细信息,请参阅用户订阅模式的配置

  • classicsimplified 节点通信模式:池可配置为以下两种节点通信模式之一:经典或 简化。 在经典节点通信模型中,Batch 服务启动与计算节点的通信,并且计算节点还需要与 Azure 存储通信。 在简化的节点通信模型中,计算节点启动与 Batch 服务的通信。 由于所需的入站/出站连接范围缩小,并且基线操作不需要 Azure 存储出站访问,因此建议使用简化的节点通信模型。 Batch 服务的一些未来改进也需要简化的节点通信模型。 经典节点通信模型将于 2026 年 3 月 31 日停用

  • 作业和任务运行时间注意事项:如果作业主要包括短时间运行的任务,且预期的任务总数较少,即作业的总预期运行时间不长,则请勿为每个作业分配新池。 节点的分配时间会缩减作业运行时间。

  • 多个计算节点:不保证各个节点始终可用。 硬件故障、操作系统更新和其他许多问题虽然不太常见,但它们可能会导致个别节点脱机。 如果 Batch 工作负荷需要具有确定性且有保证的进度,则你应该分配包含多个节点的池。

  • 生命周期结束 (EOL) 日期临近的映像:强烈建议避免使用 Batch 支持生命周期结束 (EOL) 日期临近的映像。 可以通过 ListSupportedImages APIPowerShellAzure CLI 发现这些日期。 你有责任定期查看与你的池相关的 EOL(生命周期结束)日期,并在 EOL 日期到来前迁移你的工作负载。 如果您使用带有指定节点代理的自定义映像,请确保遵循该自定义映像所派生自或与之匹配的映像的 Batch 支持终止日期。 没有指定 batchSupportEndOfLife 日期的映像表示 Batch 服务尚未确定该日期。 缺少日期并不表示将无限期地支持相应的映像。 将来随时可以添加或更新 EOL 日期。

  • 即将达到生命周期结束 (EOL) 日期的 VM SKU: 与 VM 映像一样,VM SKU 或系列也可能达到 Batch 支持生命周期结束日期 (EOL)。 可以通过 ListSupportedVirtualMachineSkus APIPowerShellAzure CLI 发现这些日期。 通过创建具有适当支持的 VM SKU 的新池,规划将工作负荷迁移到非 EOL VM SKU。 某个 VM SKU 没有关联的 batchSupportEndOfLife 日期,并不表示该特定 VM SKU 会无限期获得支持。 将来随时可以添加或更新 EOL 日期。

  • 唯一资源名称:Batch 资源(作业、池等)通常会随着时间推移不断创建和删除。 例如,你可能会在星期一创建一个池,在星期二将它删除,然后在星期四又创建一个类似的池。 应为创建的每个新资源指定一个以前从未用过的唯一名称。 可以使用 GUID(作为整个资源名称或其中的一部分),或者通过在资源名称中嵌入资源的创建日期和时间来建立唯一性。 Batch 支持 DisplayName,此属性可为资源指定一个更易读的名称(即使实际资源 ID 不够易读)。 使用唯一名称可以更方便地区分哪个特定资源在日志和指标中产生了影响。 此外,如果你需要为某个资源提交技术支持请求,这也能消除歧义。

  • 池维护或发生故障期间的连续运行: 最好让作业动态地使用池。 如果你的作业都使用同一个池,那么一旦该池出了问题,作业就有可能无法运行。 此原则对于时间敏感型工作负载尤其重要。 例如,在计划每个作业时动态选择或创建池,或通过某种方式替代池名称,以便可以绕过不正常的池。

  • 池维护和故障期间的业务连续性:有许多原因(例如内部错误或容量约束)会导致池无法增长到所需的大小。 确保可以在必要时将作业目标重新定为不同的池(也许可以通过 UpdateJob 使用不同的 VM 大小)。 避免依赖静态池 ID,并认为它永远不会被删除或发生变化。

池安全性

隔离边界

出于隔离目的,如果你的场景需要将作业或任务相互隔离,请通过将这些内容放入不同的池中进行隔离。 池是 Batch 中的安全隔离边界,默认情况下,两个池之间相互不可见或不可通信。 避免使用单独的 Batch 帐户作为安全隔离手段,除非运行 Batch 帐户的环境较大,需要隔离。

如果需要,必须对 Batch 帐户和 API 应用适当的访问控制,以防止访问 Batch 帐户下的所有池。 建议禁用共享密钥访问,并且仅允许基于 Entra 的身份验证启用 基于角色的访问控制

批处理节点代理更新

对于计算节点数不为零的池,Batch 节点代理不会自动升级。 为了确保 Batch 池接收 Batch 节点代理的最新安全修补程序和更新,需要将池大小调整为零计算节点或重新创建池。 建议留意 Batch 节点代理发行说明,以了解新 Batch 节点代理版本 发生的更改。 定期检查发布的更新可以规划升级到最新代理版本。

如果遇到 Batch 池或计算节点问题,那么在重新创建池或调整池大小之前,应下载任何节点代理日志来进行调试。 节点部分进一步介绍了此过程。

操作系统更新

建议为 Batch 池选择的 VM 映像应与发布者提供的最新安全更新同步更新。 某些映像可能会在启动时(或之后不久)执行自动包更新,这可能会干扰某些用户定向操作,例如检索包存储库更新(例如 apt update),或在 StartTask 等操作期间安装包。

建议启用“Batch 池自动 OS 升级”,这样底层 Azure 基础结构就可以协调池中的更新。 可以将此选项配置为不干扰任务执行。 自动 OS 升级并不支持 Batch 支持的所有操作系统。 有关更多信息,请参阅虚拟机规模集自动操作系统升级支持矩阵。 对于 Windows 操作系统,请确保在对 Batch 池使用自动操作系统升级时,不要启用属性 virtualMachineConfiguration.windowsConfiguration.enableAutomaticUpdates

Azure Batch 不会验证允许与服务一起使用的映像是否具有最新的安全更新,也不保证其具有最新安全更新。 对映像的更新由映像发布者负责,不由 Azure Batch 负责。 对于在 microsoft-azure-batch 下发布的某些映像,无法保证这些映像会与其上游来源映像保持同步更新。

池生存期和计费

池生存期可能根据分配方法和应用于池配置的选项而有所不同。 池可以具有任意生存期,并且在任意时间点,计算节点数可能会变化。 你需要负责显式管理池中的计算节点,或者通过服务提供的功能(自动缩放自动池)进行管理。

  • 池重新创建: 避免每天删除和重新创建池。 而是创建一个新池,然后更新现有作业,使其指向该新池。 将所有任务移到新池后删除旧池。

  • 池效率和计费: Batch 本身不会额外收费。 但是,你需要为使用的 Azure 资源付费,例如计算、存储、网络以及 Batch 工作负载可能需要的任何其他资源。 你需要为池中的每个计算节点付费,不管这些节点处于何种状态。

  • 临时 OS 磁盘:虚拟机配置池可使用临时 OS 磁盘来避免产生与托管磁盘相关的额外费用,临时磁盘会在 VM 缓存或临时 SSD 上创建 OS 磁盘。

池分配失败

在首次分配或后续调整池大小过程中的任何阶段,都可能发生内存池分配失败。 发生这种失败的可能原因是区域中出现了暂时性的容量耗尽,或 Batch 所依赖的其他 Azure 服务发生故障。 核心配额没有保障,而且存在限制。

计划外停机

Azure 中的 Batch 池可能会遇到停机事件。 要认识到可能会出现问题,并且应将工作流设计为能够适应重复执行。 如果节点发生故障,Batch 会代表你自动尝试恢复这些计算节点。 这种恢复可能会触发在已还原节点或其他可用节点上重新计划任何正在运行的任务。 若要详细了解中断的任务,请参阅重试设计

自定义映像池

使用虚拟机配置创建 Azure Batch 池时,需指定一个虚拟机 (VM) 映像,为池中每个计算节点提供操作系统。 可以使用受支持的 Azure 市场 映像创建池,也可以使用 Azure Compute Gallery 映像创建自定义映像。 虽然也可使用托管映像创建自定义映像池,但建议尽可能使用 Azure Compute Gallery 创建自定义映像。 使用 Azure Compute Gallery 可帮助你更快地预配池、缩放更大数量的 VM,以及提高预配 VM 时的可靠性。

第三方映像

可以使用已发布到 Azure 市场中的第三方映像来创建池。 对于采用用户订阅模式的 Batch 帐户,在使用某些第三方映像创建池时,你可能会看到错误“由于市场购买资格检查,分配失败”。 若要解决此错误,请接受映像发布者设置的术语。 可以通过 Azure PowerShellAzure CLI 来实现此目的。

容器池

使用虚拟网络创建 Batch 池时,指定的虚拟网络和默认 Docker 网桥之间可能存在交互副作用。 Docker 默认会创建一个网络网桥,其子网规范为 172.17.0.0/16。 请确保 Docker 网桥和虚拟网络之间没有冲突的 IP 范围。

Docker Hub 限制了映像拉取的数量。 请确保您的工作负载不要超过适用于基于 Docker Hub 的映像的已公布速率限制。 建议直接使用 Azure 容器注册表或利用 ACR 中的工件缓存

Azure 区域依赖项

如果你有时间敏感型工作负载或生产工作负载,则你不应依赖单个 Azure 区域。 有些问题虽然极少出现,但可能会影响整个区域。 例如,如果处理任务需要在特定时间开始,请考虑在开始时间之前很早就对主区域中的池进行扩容。 如果该池扩展失败,则可以退而改为在一个或多个备用区域中扩容池。

如果另一个池出现问题,跨不同区域中多个帐户的池可提供一个现成的且易于访问的备份。

作业

作业是一种用于容纳数百、数千甚至数百万个任务的容器。 创建作业时,请遵循这些指导原则。

更少作业,更多任务

使用一个作业运行单个任务是低效的做法。 例如,使用包含 1000 个任务的单个作业,比创建 100 个作业并在每个作业中包含 10 个任务更高效。 如果使用了 1000 个作业,在每个作业中包含单个任务是最低效、速度最慢且成本最高的做法。

请确保避免设计同时需要数千个活动作业的 Batch 解决方案。 不存在针对任务的配额,因此,通过尽量少的作业执行尽量多的任务可以有效利用作业和作业计划配额

作业生存期

在从系统中删除之前,Batch 作业生存期是无限的。 其状态表示它是否还能接受更多任务进行调度。

除非显式终止作业,否则作业不会自动转换为已完成状态。 可以通过 onAllTasksComplete 属性或 maxWallClockTime 自动触发此操作。

存在默认的活动作业和作业计划配额。 处于已完成状态的作业和作业计划不会计入此配额。

即使作业已完成,也可在不再需要时将其删除。 虽然已完成的作业不计入活动作业配额,但定期清理已完成的作业会很有帮助。 例如,如果作业总数是较小的集(即使对请求应用了适当的筛选器),列出作业将更高效。

任务

任务是构成作业的单个工作单位。 任务由用户提交,并由 Batch 调度到计算节点上。 以下部分提供了有关设计任务以处理问题并保持高效性能的建议。

保存任务数据

计算节点具有瞬态性。 自动汇集自动缩放等 Batch 功能很容易使节点消失。 当节点离开池时(由于调整大小或删除池),这些节点上的所有文件也会一并删除。 由于这种行为,任务应在完成之前,将其输出从其运行所在的节点移出,并存入持久化存储。 同样,如果任务失败,则应将诊断失败问题所需的日志移到持久存储。

Batch 内置了对 Azure 存储的支持,可通过 OutputFiles 上传数据,也支持各种共享文件系统;或者,你也可以在任务中自行上传数据。

管理任务生命周期

当不再需要这些任务时将其删除,或者设置 retentionTime 任务约束。 如果设置了 retentionTime,当 retentionTime 过期时,Batch 会自动清理该任务占用的磁盘空间。

删除任务可以实现两种目的:

  • 确保作业中不会出现任务积压。 此操作有助于避免难以查找你感兴趣的任务的情况(因为必须通过“已完成”任务进行筛选)。
  • 清理节点上的对应任务数据(前提是 retentionTime 尚未被触发)。 此操作有助于确保节点中不会填满任务数据且不会耗尽磁盘空间。

注意

对于刚刚提交到 Batch 的任务,DeleteTask API 调用最多需要 10 分钟才能生效。 在此生效之前,其他任务可能无法被调度。 这是因为 Batch 计划程序仍会尝试计划刚刚删除的任务。 如果想在提交不久后删除一个任务,请改为终止该任务(因为终止任务请求会立即生效)。 然后在 10 分钟后删除任务。

以集合形式提交大量任务

任务可以单独提交,也可以成组提交。 执行批量任务提交时,每次以最多包含 100 个任务的集合形式提交任务可以减少开销并缩短提交时间。

适当地设置每个节点的最大任务数

Batch 支持在节点上超额订阅任务(即运行的任务数超过节点的核心数)。 你需要确保你的任务大小与池中的节点相匹配。 例如,如果你尝试在设置了 taskSlotsPerNode = 8 的池中将 8 个任务调度到一个节点上,并且每个任务都占用 25% 的 CPU,则体验可能会变差。

为重试和重新执行而设计

Batch 可以自动重试任务。 有两种类型的重试:用户控制的重试和内部重试。 用户控制的重试由任务的 maxTaskRetryCount 指定。 如果任务中指定的程序以非零退出代码退出,则该任务最多会重试到 maxTaskRetryCount 的值。

可能会由于计算节点上发生故障(例如,在运行任务时无法更新内部状态或节点上发生故障)而在内部重试任务,不过,这种情况很罕见。 将尽可能地在同一计算节点上重试任务,直到达到内部限制,重试失败后将放弃该任务,并推迟任务以让 Batch 重新对其进行计划(可能会将其安排在不同的计算节点上)。

生成持久任务

在设计任务时应当使其能够承受故障并提供重试机制。 对于长时间运行的任务,此原则尤其重要。 确保任务即使多次运行也能生成相同的单一结果。 实现此结果的一种方法是使任务“搜寻目标”。另一种方法是确保任务具有幂等性(无论任务运行多少次,都将具有相同的结果)。

一个常见示例是通过某个任务将文件复制到计算节点。 简单的方法是每次运行任务时复制所有指定的文件,但这种方法非常低效,且不能承受故障。 替代方法是创建一个任务来确保文件位于计算节点上,该任务不会重新复制已存在的文件。 通过这种方式,在该任务中断时,它会从上次中断的位置继续运行。

避免执行时间过短

仅运行一两秒的任务并不理想。 尝试在单个任务中完成大量工作(持续时间至少为 10 秒,长至数小时甚至数天)。 如果每个任务执行一分钟(或更长时间),则调度开销将仅占总体计算时间的很少一部分。

在 Windows 节点上执行短任务时使用池作用域

在 Batch 节点上调度任务时,可以选择以任务范围还是池范围运行该任务。 如果任务只运行很短的时间,由于为该任务创建自动用户帐户所需的资源,任务范围可能效率不高。 为了提高效率,可考虑将这些任务设为池范围。 有关更多信息,请参阅以具有池作用域的自动用户身份运行任务

节点

计算节点是专门用于处理一部分应用程序工作负载的 Azure 虚拟机 (VM) 或云服务 VM。 使用节点时,请遵循以下指导原则。

启动任务:生命周期和幂等性

与其他任务一样,节点启动任务应该是幂等的。 当计算节点或 Batch 代理重启时,将重新运行启动任务。 幂等任务是指在多次运行时都会产生相同结果的任务。

启动任务不应是长期运行的任务,也不应与计算节点的生命周期绑定。 如果需要启动本质上是服务或类似服务的程序,请构造一个启动任务,使这些程序能够由操作系统工具(例如 Linux 或 Windows 服务上的 systemd)启动和管理。 启动任务仍应设计为幂等的,以便如果这些程序此前已作为服务安装,后续再次执行启动任务时也能得到正确处理。

提示

当 Batch 重新运行启动任务时,它会尝试删除然后重新创建启动任务目录。 如果 Batch 无法重新创建启动任务目录,则计算节点将无法启动启动任务。

这些服务不得对节点上 Batch 托管目录中的任何文件创建文件锁,否则 Batch 会由于存在文件锁而无法删除这些目录。 例如,不要将服务配置为直接从启动任务的工作目录启动,而应以幂等的方式将文件复制到其他位置。 然后使用操作系统工具从该位置安装服务。

独立节点

对于具有合规或监管要求的工作负载,请考虑使用隔离 VM 大小。 虚拟机配置模式下支持的独立大小包括 Standard_E80ids_v4Standard_M128msStandard_F72s_v2Standard_G5Standard_GS5Standard_E64i_v3。 有关独立 VM 大小的详细信息,请参阅 Azure 中的虚拟机隔离

避免在 Windows 中创建目录联接

目录联接(有时也称为目录硬链接)在清理任务和作业的过程中较难处理。 请使用符号链接(软链接),而不要使用硬链接。

临时磁盘和 AZ_BATCH_NODE_ROOT_DIR

Batch 依赖 VM 临时磁盘(对于与 Batch 兼容的 VM 大小)来存储与任务执行相关的元数据,以及每次任务执行在该临时磁盘上产生的任何产物。 这些临时磁盘装载点或目录的示例:/mnt/batch/mnt/resource/batchD:\batch\tasks。 不支持替换、重新装载、接合、符号链接或以其他方式重定向这些装载点和目录或任何父目录,此类操作可能导致不稳定。 如果需要更多磁盘空间,请考虑使用具有满足要求的临时磁盘空间的 VM 大小或系列,或附加数据磁盘。 有关详细信息,请参阅下一部分,其中介绍了如何为计算节点附加和准备数据磁盘。

附加并准备数据磁盘

如果将每个计算节点指定为 Batch 池实例的一部分,则为其附加的数据磁盘规格将完全相同。 只能将新的数据磁盘附加到 Batch 池。 这些附加到计算节点的数据磁盘不会自动分区、格式化或装载。 你需要负责将这些操作作为启动任务的一部分来执行。 这些启动任务必须采用幂等设计。 可以在计算节点上重新执行启动任务。 如果启动任务不是幂等的,则可能会导致数据磁盘上的数据丢失。

提示

在 Linux 中装载数据磁盘时,如果将磁盘装入点嵌套在 Azure 临时装入点(例如 /mnt/mnt/resource)下,应注意不引入依赖项争用。 例如,如果这些挂载操作由操作系统自动执行,则临时磁盘的挂载与将数据磁盘挂载到父目录下之间可能会发生竞争。 应当采取措施来确保通过可用的工具(例如 systemd)强制实施适当的依赖关系,或者在幂等数据磁盘准备脚本中将数据磁盘的装载推迟到启动任务。

在 Linux Batch 池中准备数据磁盘

Linux 中的 Azure 数据磁盘显示为块设备,并为其分配了典型的 sd[X] 标识符。 请不要依赖于静态 sd[X] 分配,因为这些标签是在启动时动态分配的,不能保证在完成首次启动和任何后续启动之间保持一致。 应该通过 /dev/disk/azure/scsi1/ 中提供的映射来识别附加的磁盘。 例如,如果在AddPool API 中为数据磁盘指定了 LUN 0,则此磁盘将显示为 /dev/disk/azure/scsi1/lun0。 例如,如果你列出此目录,则可能会看到:

user@host:~$ ls -l /dev/disk/azure/scsi1/
total 0
lrwxrwxrwx 1 root root 12 Oct 31 15:16 lun0 -> ../../../sdc

无需在你的准备脚本中将该引用还原为 sd[X] 映射,而是直接引用该设备。 在此示例中,此设备为 /dev/disk/azure/scsi1/lun0。 可以将此 ID 直接提供给 fdiskmkfs 以及工作流所需的任何其他工具。 或者,可以将 lsblkblkid 结合使用来映射磁盘的 UUID。

若要详细了解 Linux 中的 Azure 数据磁盘(包括查找数据磁盘和 /etc/fstab 选项的备用方法),请查看此文章。 在将该方法投入生产环境使用之前,请确保不存在提示说明中所述的依赖关系或竞争条件。

在 Windows Batch 池中准备数据磁盘

附加到 Batch Windows 计算节点的 Azure 数据磁盘将显示为未分区且未格式化。 你需要在启动任务中枚举带有 RAW 分区的磁盘,并对其执行操作。 可以使用 Get-Disk PowerShell cmdlet 检索此信息。 例如,你可能会看到:

PS C:\Windows\system32> Get-Disk

Number Friendly Name Serial Number                    HealthStatus         OperationalStatus      Total Size Partition
                                                                                                             Style
------ ------------- ------------- ------------         ----------------- ---------- ----------
0      Virtual HD                                     Healthy              Online                      30 GB MBR
1      Virtual HD                                     Healthy              Online                      32 GB MBR
2      Msft Virtu...                                  Healthy              Online                      64 GB RAW

其中磁盘编号 2 是附加到此计算节点的未初始化数据磁盘。 然后可以根据工作流的需要对这些磁盘进行初始化、分区和格式化。

若要详细了解 Windows 中的 Azure 数据磁盘(包括示例 PowerShell 脚本),请查看此文章。 在提升到生产使用之前,请确保验证任何示例脚本是否具有幂等性。

收集批处理代理日志

如果发现节点的行为或节点上运行的任务出现问题,请在解除分配有问题的节点之前收集 Batch 代理日志。 可以使用“上传 Batch 服务日志”API 收集 Batch 代理日志。 这些日志可以作为 Azure 支持工单的一部分提供,并将有助于问题的故障排除和解决。

批量 API

超时失败

超时失败不一定指示服务未能处理请求。 发生超时失败时,应根据情况重试操作或检索资源的状态,以验证操作的状态是成功还是失败。

连接

查看以下有关 Batch 解决方案中的连接性的指导。

网络安全组 (NSG) 和用户定义的路由 (UDR)

在虚拟网络中预配 Batch 池时,请确保严格遵守有关使用 BatchNodeManagement.region 服务标记、端口、协议和规则方向的指导原则。 强烈建议使用服务标记,不要使用基础 Batch 服务 IP 地址,因为这些地址可能会随着时间的推移而变化。 直接使用 Batch 服务 IP 地址可能会导致 Batch 池不稳定、受干扰或中断。

对于用户定义的路由 (UDR),建议使用 BatchNodeManagement.region服务标记,而不是 Batch 服务 IP 地址,因为这些地址可能会随发生更改。

遵守 DNS

确保系统遵守 Batch 帐户服务 URL 的 DNS 生存时间 (TTL)。 此外,请确保 Batch 服务客户端以及 Batch 服务的其他连接机制不依赖于 IP 地址。

任何返回 5xx 级状态代码且响应头中包含“Connection: close”标头的 HTTP 请求,都需要调整 Batch 服务客户端的行为。 你的 Batch 服务客户端应遵循建议关闭现有连接,重新解析 Batch 帐户服务 URL 的 DNS,然后在新的连接上尝试后续请求。

自动重试请求

确保您的 Batch 服务客户端配置了适当的重试策略,以便自动重试请求,即使在正常运行期间也是如此,而不应仅在服务维护期间这样做。 这些重试策略的间隔时间应该至少为 5 分钟。 各种 Batch SDK(例如 .NET RetryPolicyProvider 类)都附带了自动重试功能。

静态公共 IP 地址

通常,Batch 池中的虚拟机是通过公共 IP 地址访问的,这些地址在池的生命周期中会发生更改。 这种动态性会使与数据库或其他限制访问某些 IP 地址的外部服务交互变得困难。 若要解决这种忧虑,可以使用由你控制的一组静态公共 IP 地址创建一个池。 有关详细信息,请参阅使用指定的公用 IP 地址创建 Azure Batch 池

批处理节点的底层依赖项

设计 Batch 解决方案时,请考虑以下依赖项和限制。

系统创建的资源

Azure Batch 在 VM 上创建和管理一组用户和组,这些不应受到更改:

窗户:

  • 名为“PoolNonAdmin”的用户
  • 名为“WATaskCommon”的用户组

Linux:

  • 名为“_azbatch”的用户

提示

这些用户或组的命名是实现项目,随时可能会更改。

文件清理

任务保留期到期后,Batch 会主动尝试清理任务运行所在的工作目录。 你应负责清理在此目录之外写入的所有文件,以避免占用磁盘空间。

如果在 Windows 上从启动任务工作目录运行服务,则会阻止对工作目录的自动清理,因为文件夹仍在使用中。 此操作将导致性能下降。 若要解决此问题,请将该服务的目录更改为不受 Batch 管理的单独目录。

后续步骤